[英]Executing tasks with exception handling while updating GUI during tasks
早上。
(尝试做):我尝试并行执行多个任务。 每个任务都使用for循环遍历文本文件的某个部分(第一个任务=第1-10行。第二个任务=第11-20行,依此类推)。 在每行检查结束时,将引发一个事件,并且GUI线程更新UI,即“已检查X行”。
(坚持):我不知道该怎么做,但仍然能够正确处理异常。 据我所知,我需要打电话
task.Wait();
要么
task.WaitAll();
但是通过调用它,UI线程只是在那里等待,我在任务中触发的任何事件以更新UI都只是添加到UI队列中。
有谁知道如何解决这个问题?
注意:如果这很愚蠢,但我对线程有问题,我事先表示歉意。
因为任务将所有异常都捆绑到AggregateException中,并且如果我调用task.Waitall(); UI线程似乎只是等待任务完成或引发异常。
一种选择是将另一个任务附加到您的任务上,作为处理任何异常的“处理程序”。
这是一个例子:
var task = Task.Factory.StartNew(() =>
{
throw new Exception("oops!");
});
// attach an exception-handling task
task.ContinueWith(previousTask =>
{
// do something with the exception
Console.WriteLine(previousTask.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
请注意, ContinueWith
附带的任务具有TaskContinuationOptions.OnlyOnFaulted
,这意味着它仅在与其TaskContinuationOptions.OnlyOnFaulted
的任务引发异常时才运行。
这样,您的异常可以异步处理,并且您无需等待任何事情。
但是,由于您要执行并行for循环,因此我可能会执行以下操作:
Task.Factory.StartNew(() =>
{
try
{
Parallel.For(..., i =>
{
...
});
}
catch (AggregateException e)
{
// handle it somehow
}
});
这样,您的主任务将等待所有子任务,但是产生它的UI线程不必等待。
您必须确保的主要事情是catch
子句(或上一个示例中的处理任务) 永远不会引发异常。
一种选择(最简单的方法)是在引发异常的线程中处理异常。
因此,您需要在执行方法中尝试捕获-然后您的工作取决于设计,例如,可以引发UI可以处理的错误事件(仍在异常线程的上下文中)。
另一种选择是,您可以将您的任务调度代码(即调用WaitAll()的代码)作为BackgroundWorker进行启动-然后,这将使UI可以自由地处理其工作(处理其他输入)-这可能是更好的方法这样做,但可能需要一些重构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.