简体   繁体   English

使用Task进行长时间运行,如果有,则显示Exception

[英]Do long running process with Task and showing Exception if there is one

I am testing for using Task in my application. 我正在测试在我的应用程序中使用Task。 Now, I have done the fallowing: 现在,我做了以下事情:

var task = Task.Factory.StartNew(() => {
   // long running process
   throw new Exception("test"); // throwing TestException
});
task.ContinueWith(x => MyErrorHandler(task.Exception), TaskContinuationOptions.OnlyOnFaulted);

void MyErrorHandler(Exception error) {
   MessageBox.Show(error.Message);
}

The idea is, that the long running process will executed and the user can working on without any blocking of the UI. 这个想法是,将执行长时间运行的进程,用户可以在不阻止UI的情况下继续工作。 If there was a problem (exception) it will be show, after the long running process has finished (in the normal case, there would be no exception) 如果出现问题(异常),则在长时间运行的过程完成后将显示(在正常情况下,没有异常)

Is this the correct way I have used it or does I have to do it on another way? 这是我使用它的正确方法还是我必须以另一种方式进行? Are there any problems, which I can get on this way and I don't see now? 有没有问题,我可以通过这种方式获得,现在我看不到?

This will work, as you're explicitly checking Task.Exception , which will prevent the exception from being unobserved. 这将起作用,因为您显式检查Task.Exception ,这将防止异常被Task.Exception

I would make a couple of recommendations here. 我会在这里提出一些建议。

First, if this is truly a long running task, you might want to specify that: 首先,如果这确实是一个长期运行的任务,您可能需要指定:

var task = Task.Factory.StartNew(() => {
   // long running process
   throw new Exception("test"); // throwing TestException
}, TaskCreationOptions.LongRunning);

Second, you don't need the closure over task : 其次,您不需要关闭task

// use x.Exception, since x is the task
task.ContinueWith(x => MyErrorHandler(x.Exception), TaskContinuationOptions.OnlyOnFaulted);

You may also want to have this run on the main thread, especially if you decide you want to use something more elaborate (in your UI) for reporting: 您可能还希望在主线程上运行此操作,特别是如果您决定要使用更精细的(在您的UI中)进行报告:

// This will work if MyErrorHandler uses a UI control, since it'll marshal back to the current synchronization context
task.ContinueWith(x => MyErrorHandler(x.Exception), 
    CancellationToken.None,
    TaskContinuationOptions.OnlyOnFaulted,
    TaskScheduler.FromCurrentSynchronizationContext());

(This is only required if you're going to use UI controls, etc, in your error handler.) (只有在错误处理程序中使用UI控件等时才需要这样做。)

Also - If you're using .NET 4.5 or the async targetting pack for .NET 4, you can simplify this by using the new async / await support. 此外 - 如果您使用的是.NET 4.5或.NET 4的异步目标包,则可以使用新的async / await支持来简化此操作。 If you flag your method as async , you can do: 如果将方法标记为async ,则可以执行以下操作:

try
{
    await Task.Factory.StartNew(() => {
           // long running process
           throw new Exception("test"); // throwing TestException
        }, TaskCreationOptions.LongRunning);
}
catch(Exception error)
{
      MyErrorHandler(error);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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