我正在將一些異步/等待代碼轉換爲鏈接任務,因此我可以在發佈的框架中使用它。該AWAIT代碼看起來像這樣任務鏈接沒有TaskCompletionSource?
public async Task<TraumMessage> Get() {
var message = await Invoke("GET");
var memorized = await message.Memorize();
return memorized;
}
其中
Task<TraumMessage> Invoke(string verb) {}
Task<TraumMessage> Memorize() {}
我希望鏈Invoke
和Memorize
返回由Memorize
產生的任務,但導致Task<Task<TraumMessage>
。我已經結束了該解決方案是一個TaskCompletionSource<TraumMessage>
我的信號:
public Task<TraumMessage> Get() {
var completion = new TaskCompletionSource<TraumMessage>();
Invoke("GET").ContinueWith(t1 => {
if(t1.IsFaulted) {
completion.SetException(t1.Exception);
return;
}
t1.Result.Memorize().ContinueWith(t2 => {
if(t2.IsFaulted) {
completion.SetException(t2.Exception);
return;
}
completion.SetResult(t2.Result);
});
});
return completion.Task;
}
有沒有辦法做到這一點沒有TaskCompletionSource
?
感謝Jon Skeet的EduAsync系列,我查看了async/await的底層,它基本上構建了一個運行狀態機的類。我之前也使用過這種方法,但比TCS方法更乏味。 –
啊,好吧,我還想過這麼多,除非你想阻止等待第二項任務繼續進行的第一項任務的繼續,否則純粹的繼續是無法實現的。如果星星是對齊的,那麼盜取工作可能意味着其中的開銷很小,但由於理論上不知道第二個任務是如何創建的(可能完全是差異化任務調度程序或APM),因此無法保證。所以你必須假設你會阻止等待結果的線程。如果你想看看我的意思是讓我知道,我會更新我的答案。 –
在http://blogs.msdn.com/b/pfxteam/archive/2010/11/21/10094564.aspx Stephen Taub將'TaskCompletionSource'封裝在名爲'Then'的助手方法中以實現此模式。 – Govert