我正在运行10k个任务,每个任务都将一批数据发送到Azure存储表。
如果我使用async await下面的第一个方法返回正在运行的任务,那么任务执行的速度非常慢,而且从几秒钟内爬升到10,100秒等就会越来越慢。
如果我使用下面的第二种方法返回新的运行任务,它们会很快运行!每项任务只需几十毫秒。
为什么这里有这么大的差异?我错过了什么?
在我的任务创建结束时,我做了一个简单的Task.WaitAll(allTasks.ToArray())。
private static async Task ExecuteBatch(TableBatchOperation tableBatchOperation, CloudTable cloudTable, TextWriter log)
{
var stopwatch = Stopwatch.StartNew();
await cloudTable.ExecuteBatchAsync(tableBatchOperation);
stopwatch.Stop();
log.WriteLine("Committed " + tableBatchOperation.Count + " records in " + stopwatch.Elapsed.TotalSeconds + " seconds.");
}
private static Task ExecuteBatch2(TableBatchOperation tableBatchOperation, CloudTable cloudTable, TextWriter log)
{
return Task.Run(() =>
{
var stopwatch = Stopwatch.StartNew();
cloudTable.ExecuteBatch(tableBatchOperation);
stopwatch.Stop();
log.WriteLine("Committed " + tableBatchOperation.Count + " records " + " in " + stopwatch.Elapsed.TotalSeconds + " seconds.");
});
}
aftger
答案 0 :(得分:2)
因为当你使用await
时,你实际上是在等待"结果,如果你阻止ExecuteBatch
,它就不会结束,直到ExcecuteBatchAsync
结束。
另一方面,ExecuteBatch2
没有"等待"任何东西。即使您阻止ExecuteBatch2
响应,ExecuteBatchAsync
操作也会并行启动,ExecuteBatch2
结束,尽管ExecuteBatchAsync
启动的任务仍在运行。
<强>更新强>
1| var stopwatch = Stopwatch.StartNew();
2| await cloudTable.ExecuteBatchAsync(tableBatchOperation);
3| stopwatch.Stop();
4| log.WriteLine("Committed " + tableBatchOperation.Count + " records in " + stopwatch.Elapsed.TotalSeconds + " seconds.");
在第一种方法中,因为您正在等待,所以在第2行结束之前,您将无法进入第3行。
然而,在你的第二种方法中:
1| var stopwatch = Stopwatch.StartNew();
2| cloudTable.ExecuteBatchAsync(tableBatchOperation);
3| stopwatch.Stop();
4| log.WriteLine("Committed " + tableBatchOperation.Count + " records " + " in " + stopwatch.Elapsed.TotalSeconds + " seconds.");
您将立即从第2行到达第3行,因为ExecuteBatchAsync
并行发生,没有任何东西使得线程阻塞结果。如果你做cloudTable.ExecuteBatchAsync(tableBatchOperation).Wait()
,你可能会得到与第一种方法相同的结果。