我有很長時間的運行處理,我想在後臺任務中執行。在任務結束時,我想表示它已完成。所以基本上我有兩個異步任務,我想在後臺運行一個接一個。序列化異步任務和異步繼續
我在繼續執行此操作,但是繼續操作是在完成初始任務之前開始的。預期的行爲是繼續只在完成初始任務後運行。
下面是一個說明該問題的一些示例代碼:
// Setup task and continuation
var task = new Task(async() =>
{
DebugLog("TASK Starting");
await Task.Delay(1000); // actual work here
DebugLog("TASK Finishing");
});
task.ContinueWith(async (x) =>
{
DebugLog("CONTINUATION Starting");
await Task.Delay(100); // actual work here
DebugLog("CONTINUATION Ending");
});
task.Start();
的DEBUGLOG功能:
static void DebugLog(string s, params object[] args)
{
string tmp = string.Format(s, args);
System.Diagnostics.Debug.WriteLine("{0}: {1}", DateTime.Now.ToString("HH:mm:ss.ffff"), tmp);
}
預期輸出:
TASK Starting
TASK Finishing
CONTINUATION Starting
CONTINUATION Ending
實際輸出:
TASK Starting
CONTINUATION Starting
CONTINUATION Ending
TASK Finishing
同樣,我的問題是爲什麼在完成初始任務之前繼續開始?如何在第一項任務完成後繼續運行?
變通辦法#1
我可以讓上面的代碼工作,如果我做INTIAL任務同步如預期 - 那就是如果我Wait
在Task.Delay
像這樣:
var task = new Task(() =>
{
DebugLog("TASK Starting");
Task.Delay(1000).Wait(); // Wait instead of await
DebugLog("TASK Finishing");
});
由於很多原因,使用Wait
這樣做很不好。一個原因是它阻塞了線程,這是我想避免的。
變通辦法#2
如果我接任務的創建,並將其移動到它自己的功能,這似乎也工作:
// START task and setup continuation
var task = Test1();
task.ContinueWith(async (x) =>
{
DebugLog("CONTINUATION Starting");
await Task.Delay(100); // actual work here
DebugLog("CONTINUATION Ending");
});
static public async Task Test1()
{
DebugLog("TASK Starting");
await Task.Delay(1000); // actual work here
DebugLog("TASK Finishing");
}
信貸的上述方法去到這個有點相關(但不重複)的問題:Use an async callback with Task.ContinueWith
解決方法#2比解決方法#1更好,如果沒有解釋爲什麼我上面的初始代碼不起作用,我可能會採取這種方法。
-1:原始代碼不工作,因爲它在必要時不使用'Unwrap()'方法。創建一個'async void' lambda當然不是所希望的,但也只是沒有使用'新任務(...)'的副作用,所以'Unwrap()'會起作用。 –
2014-09-20 19:56:37
@ 280Z28:是的,原始代碼可能會被黑客使用'新的任務'和'Unwrap';然而,新的代碼會工作*,因爲*它會避免一個'異步void'lambda。它仍然不如基於Task.Run的解決方案。 –
2014-09-20 19:59:12
+1我結束了使用'Task.Run'和原來的延續。感謝您深入瞭解爲什麼我現有的代碼不起作用:lambda變成'async void'。當然,當你這樣說時,一切都變得更有意義。那麼,爲什麼我要使用延續?那麼,這裏試圖解釋太多了,儘管它與[這個問題]有很大關係(http://stackoverflow.com/questions/11878654/winrt-loading-data-while-keeping-the-ui-響應)。 – 2014-09-22 01:32:36