繁体   English   中英

在任务期间更新GUI时执行具有异常处理的任务

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM