2011-12-09 59 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) { } }); 

似乎更加清晰,反應更靈敏。