2014-07-03 44 views
4

考慮下面的代碼在調用異步異步方法和的TaskScheduler /伺機

async Task<int> foo() 
{ 
    await Task.Delay(1000); 
    return 42; 
} 

... 
// OPTION 1 

Task t = Task.Factory.StartNew(foo, 
      CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); 

t.Wait(); 


... 
// OPTION 2 
Task t = foo(); 
t.Wait() 

的問題

  1. 是哪兩個呼叫選項之間的實質性區別?

  2. 在選項1.假設我重寫默認的TaskScheduler。等待foo方法 - 將使用哪個TaskScheduler?它會使用默認還是傳遞給父任務的參數?

+1

選項2從來沒有開始一個線程? –

+1

@亨克它啓動並執行 – Boris

+0

但不是在一個線程。 –

回答

3

在一般情況下,雖然,「選項1」將創建一個新的任務一個包裝調用foo(),有效地使一個Task<Task<int>>。當你打電話給.Wait()時,它不會等待內部任務完成,因爲內部任務將立即返回(只要Task.Delay)就會被觸發。

至於你關於使用非默認的TaskScheduler的問題,一般來說它不會改變行爲,除非它可能會阻塞,直到自定義調度程序啓動任務。沒有關於調度程序的更多信息,就不可能確切知道會發生什麼。

但是,第二個選項將阻塞,直到延遲完成,因爲它將啓動任務,並阻塞,直到延遲完成。

+0

你說await會使用用於創建foo的自定義調度器嗎? – Boris

+0

@Boris否,但'Task.Factory.StartNew'將使用您的調度程序,這可能會或可能不會真正開始「任務」:) –

+0

對不起,...我完全困惑:(據我瞭解如果我有async方法,它使用內部等待,編譯器有效地創建包含方法部分作爲單獨任務的任務鏈。現在,我怎樣才能確保每個這些任務都使用我的自定義任務調度程序來調度? – Boris