2013-10-31 111 views
26

快速的問題,我想等待第二推出異步任務沒有返回值前。
這是否正確嗎?延遲然後執行任務

Task.Delay(1000) 
    .ContinueWith(t => _mq.Send(message)) 
    .Start(); 

異常會發生什麼情況?

+0

爲什麼使用異步CTP?最終版本已經出現很久了。如果您可以使用異步方法,則不需要手動使用ContinueWith - 只是等待延遲。你能給更多的背景嗎? –

+1

是的,這是最好的方式。 異常處理: http://stackoverflow.com/questions/12980712/what-is-the-best-way-to-catch-exception-in-task http://stackoverflow.com/questions/5983779/catch-exception-that-is-thrown-in-different-thread – Nahum

+0

@jon:錯誤的標籤:)它正在windows服務中使用。 – David

回答

28

首先,Start()僅適用於使用構造函數Task(例如new Task(() => _mq.Send(message)))創建的(非常罕見)Task。在所有其他情況下,它會拋出異常,因爲Task已經啓動或正在等待另一個Task

現在,可能要做到這一點是把代碼放到一個單獨的async方法和使用await的最佳方式:

async Task SendWithDelay(Message message) 
{ 
    await Task.Delay(1000); 
    _mq.Send(message); 
} 

如果你這樣做,從Send()方法的任何異常都將在結束返回Task

如果你不想這樣做,使用ContinueWith()是一個合理的方法。在這種情況下,將從ContinueWith()返回Task

此外,根據_mq的類型,考慮使用SendAsync(),如果類似的東西可用。

0

如果您的任務爲Wait,您將能夠觀察到任何異常情況。

由運行 任務內的用戶代碼拋出

未處理的異常傳播回聯接線程,除了在 某些情況下被本主題後面描述。當您使用靜態或實例Task.Wait或 Task.Wait方法之一傳播異常 ,並且您通過將調用 包含在try-catch語句中來處理它們。從Exception Handling (Task Parallel Library)

摘錄小心計時。任務使用調度程序,並且不保證在您說'去'時啓動。您的代碼將保證至少延遲1000毫秒後將其告知Start,但不能保證爲1000毫秒恰好爲

6

你能趕上在任務拋出的任何異常,如果你等待任務完成:

要知道,你的異常在任務拋出將是內一個

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      Task task = Task.Delay(1000) 
       .ContinueWith(t => Program.throwsException()); 

      task.Wait();  
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Exception:" + ex.Message); // Outputs: Exception:One or more errors occurred. 
      Console.WriteLine("Inner exception:" + ex.InnerException.Message); // Outputs: Exception:thrown 
     } 
     Console.ReadKey(); 

    } 
    static void throwsException() 
    { 
     Console.WriteLine("Method started"); 
     throw new Exception("thrown"); 
    } 
}