2011-12-09 40 views
3

处理异常说,我有这样的代码:与任务

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线程上,我的想法是在服务调用期间不阻塞线程。

+0

它不回答你的问题,但请删除该循环等待完成。使用别的东西(manualResetEvent) –

+0

这里的主线程是一个UI线程,它不能被阻塞,这就是为什么我使用Tread.Sleep。我也不想将方法拆分为能够将线程发送到特定的方法。 – Banshee

+1

如果循环的目的是非阻塞的,你肯定是错误的:UI线程被阻塞进入睡眠状态。 –

回答

2

你并不需要使用像这样的标志只是为了等待异步任务完成:

什你可以做的基本上是与替换你的睡眠循环。使用wait()

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

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

的wait()的调用将整体AggregateException内提升任何异常。

+0

这将阻止我的UI线程如果我得到它的权利? – Banshee

+0

+1 goot要知道 –

+0

正如书面,是的。有许多重载.Wait需要一个时间参数(int毫秒或TimeSpan),并且如果任务在该等待周期期间未完成,则返回true或false。 http://msdn.microsoft.com/en-us/library/dd270644.aspx – Joe

1

从评论和发布的例子来看,您似乎希望在等待响应时返回给调用者的逻辑,然后再做一堆事情。这听起来像后来的东西包含了许多非常复杂的方法,你想写程序化。 C#团队已经听到了你的问题,并且很多人都喜欢它,并开发了异步/等待框架,它将完成C#5的工作。或者,如果它是你的选择,那么可以在这里找到一个AsyncCTP:http://www.microsoft.com/download/en/details.aspx?id=9983 HTH。

0

你为什么不写代码就像这样:

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

似乎更加清晰,反应更灵敏。