2011-04-15 74 views
6

這可能是一個非常基本的問題,但只是我想確保自己在腦海中有一席之地。 今天我正在用TPL庫進行挖掘,發現有兩種創建Task類實例的方法。任務類的實例(Task.Factory.StartNew或TaskCompletionSource)

辦法,我

Task<int> t1 = Task.Factory.StartNew(() => 
       { 
        //Some code 
        return 100; 

       }); 

路II

TaskCompletionSource<int> task = new TaskCompletionSource<int>(); 
    Task t2 = task.Task; 
    task.SetResult(100); 

現在,我只是想知道,

  1. 是否有這些實例之間有什麼區別?
  2. 如果是,那麼是什麼?

回答

4

第二個示例不會創建一個「真實」任務,即沒有任何委託可以執行任何操作。

您主要使用它來向調用者顯示一個任務接口。看一下例子上 msdn

TaskCompletionSource<int> tcs1 = new TaskCompletionSource<int>(); 
    Task<int> t1 = tcs1.Task; 

    // Start a background task that will complete tcs1.Task 
    Task.Factory.StartNew(() => 
    { 
     Thread.Sleep(1000); 
     tcs1.SetResult(15); 
    }); 

    // The attempt to get the result of t1 blocks the current thread until the completion source gets signaled. 
    // It should be a wait of ~1000 ms. 
    Stopwatch sw = Stopwatch.StartNew(); 
    int result = t1.Result; 
    sw.Stop(); 

    Console.WriteLine("(ElapsedTime={0}): t1.Result={1} (expected 15) ", sw.ElapsedMilliseconds, result); 
+2

要添加更多的細節,TaskCompletionSource是一種包裝異步操作的方式,否則當前不支持TaskFactory.FromAsync之類的操作。 TaskCompletionSource的一個示例用法是包裝基於事件的異步模式實現,如WebClient.DownloadStringAsync。有關更多示例,請參閱http://msdn.microsoft.com/en-us/magazine/ff959203.aspx – 2012-07-22 16:07:02

0

當你不燒任何異步操作遠高於1,你是從線程池消耗另一個線程(可能是浪費時間,如果你不改變默認TaskScheduler)。

但是,在方式2中,您正在生成一個完成的任務,並且在與您相同的線程中執行該任務。 TCS也可以看作無線任務(可能是錯誤的描述,但被幾個開發人員使用)。

+0

Task.StartNew是一個異步操作... – 2012-07-22 16:07:43

+0

@PeterRitchie是否讀過我寫過的內容?如果你要運行一個不需要線程切換但需要返回一個Task對象的代碼,你只會使用Task.Factory.StartNew來浪費時間。停止使用它並使用TCS。 – tugberk 2012-07-22 18:12:30

+0

@PeterRitchie和'Task.Factory.StartNew'不是一個神奇的子彈,它不是異步!你可以稱它爲多線程而不是異步。異步和多線程是不同的。 – tugberk 2012-07-22 18:15:05

相關問題