处理任务中的异常

时间:2011-12-09 12:43:46

标签: c# .net parallel-processing task

说我有这样的代码:

serviceCallFinished = false;
Task.Factory.StartNew(() => {
    response = ServiceManager.GeneralService.ServiceMethod(loginName, password);
}).ContinueWith(parentTask => { serviceCallFinished = true; });

while (!serviceCallFinished)
    Thread.Sleep(100);

if (response.UserValid) { }

在这种情况下,ServiceMethod会抛出一个Exception,但这从未显示过,相反,我会在response.UserValid上获得一个空引用?

为什么异常没有移交给我的UI线程?

注意:这是在UI线程上,我的想法是在服务调用期间不阻塞线程。

4 个答案:

答案 0 :(得分:2)

您不需要使用这样的标志只是等待异步任务完成。使用Wait()

Task t = Task.Factory.StartNew(() => {
    response = ServiceManager.GeneralService.ServiceMethod(loginName, password);
});

try
{
    t.Wait();
}
catch (AggregateException e)
{
   ...
}

Wait()调用将提升整个AggregateException中的任何异常。

答案 1 :(得分:1)

从评论和发布的示例相反,似乎您希望在等待响应时返回给调用者的逻辑,然后再做一堆事情。它听起来像之后的东西包含许多非常复杂的方法,你想在程序上编写。 C#团队已经听到了你的问题,很多人喜欢它并开发了async / await框架,它将完全按照C#5进行。或者,如果它是一个选项,那么这里有一个AsyncCTP:{{3} HTH。

答案 2 :(得分:0)

看看How to: Handle Exceptions Thrown by Tasks 还有一个很好的样本。

你能做的就是用你的睡眠循环取代:

try
{
    task.Wait();
}
catch (AggregateException ae)
{
  ...
}

答案 3 :(得分:0)

为什么不像这样编写代码:

Task.Factory.StartNew(() => 
  {
   response = ServiceManager.GeneralService.ServiceMethod(
     loginName, password);
  })
  .ContinueWith(parentTask => { if (response.UserValid) { } });

似乎更清晰,更敏感。