我有很长时间的运行处理,我想在后台任务中执行。在任务结束时,我想表示它已完成。所以基本上我有两个异步任务,我想在后台运行一个接一个。序列化异步任务和异步继续
我在继续执行此操作,但是继续操作是在完成初始任务之前开始的。预期的行为是继续只在完成初始任务后运行。
下面是一个说明该问题的一些示例代码:
// 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