简而言之,您期望ContinueWith
等待先前返回的对象。返回一个对象(甚至是一个Task
) in ContinueWith
action 对返回值不执行任何操作,它不会等待它完成,它会返回该值并传递给延续(如果存在)。
确实会发生以下情况:
- You run
SampleAsyncMethodAsync(0, scopeCount.ToString())
-
完成后,执行延续 1:
return SampleAsyncMethodAsync(1, scopeCount.ToString());
当它偶然发现await Task.Run
,它返回一个任务。即,它不会等待 SampleAsyncMethodAsync 完成。
- 然后,延续 1 被认为已完成,因为它返回了一个值(任务)
- 运行延续 2。
如果您手动等待每个异步方法,那么它将相应地运行:
for (int count = 0; count < 3; count++)
{
int scopeCount = count;
var c = SampleAsyncMethodAsync(0, scopeCount.ToString())
.ContinueWith((prevTask) =>
{
SampleAsyncMethodAsync(1, scopeCount.ToString()).Wait();
})
.ContinueWith((prevTask2) =>
{
SampleAsyncMethodAsync(2, scopeCount.ToString()).Wait();
});
}
Using ContinueWith(async t => await SampleAsyncMethodAsync...
效果不太好,因为它会导致包裹Task<Task>
结果(解释得很好here https://stackoverflow.com/questions/18697167/use-an-async-callback-with-task-continuewith).
另外,您还可以执行以下操作:
for (int count = 0; count < 3; count++)
{
int scopeCount = count;
var c = SampleAsyncMethodAsync(0, scopeCount.ToString())
.ContinueWith((prevTask) =>
{
SampleAsyncMethodAsync(1, scopeCount.ToString())
.ContinueWith((prevTask2) =>
{
SampleAsyncMethodAsync(2, scopeCount.ToString());
});
});
}
然而,它创建了某种回调地狱并且看起来很混乱。
您可以使用await
使这段代码更简洁:
for (int count = 0; count < 3; count++)
{
int scopeCount = count;
var d = Task.Run(async () => {
await SampleAsyncMethodAsync(0, scopeCount.ToString());
await SampleAsyncMethodAsync(1, scopeCount.ToString());
await SampleAsyncMethodAsync(2, scopeCount.ToString());
});
}
现在,它运行 3 个任务进行 3 次计数,每个任务将因此运行异步方法number
等于 1、2 和 3。