C# async await使任务变慢,而task.Start()使任务快速运行
我正在运行10k个任务,每个任务都会向Azure存储表发送一批数据 如果我使用下面的第一个方法async await返回正在运行的任务,那么任务的执行速度非常慢,而且越来越慢,从几秒钟上升到10100秒等等 如果我使用下面的第二种方法返回新的正在运行的任务,它们运行得非常快!每个任务只有几十毫秒 为什么这里有如此巨大的差异?我错过了什么 在任务创建结束时,我执行一个简单的task.WaitAll(allTasks.ToArray())C# async await使任务变慢,而task.Start()使任务快速运行,c#,azure,async-await,azure-table-storage,C#,Azure,Async Await,Azure Table Storage,我正在运行10k个任务,每个任务都会向Azure存储表发送一批数据 如果我使用下面的第一个方法async await返回正在运行的任务,那么任务的执行速度非常慢,而且越来越慢,从几秒钟上升到10100秒等等 如果我使用下面的第二种方法返回新的正在运行的任务,它们运行得非常快!每个任务只有几十毫秒 为什么这里有如此巨大的差异?我错过了什么 在任务创建结束时,我执行一个简单的task.WaitAll(allTasks.ToArray()) aftger因为当您使用await时实际上是在“等待”结果,
aftger因为当您使用
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()
您可能会得到与第一个方法相同的结果。在第二个方法中,您不会等待cloudTable.ExecuteBatchAsync(tableBatchOperation)代码>要完成,它只需启动然后继续。您的第二次尝试完全错误。你衡量的是任务的开始,而不是完成。是的,你是对的。我改为ExecuteBatch(同步版本),速度慢得多。这是一个打字错误。我知道这有点简单,我知道这是在盯着我的脸,但我仍然有点挣扎的答案。wait将异步调用阻塞在那里,并且仅在完成时返回。好的,但是在Task.WaitAll()调用中,我仍然会得到一个长时间阻塞的任务列表。第二个版本ExecuteBatch2的工作方式与我认为的第一个版本相同。我添加了更详细的解释。
1| var stopwatch = Stopwatch.StartNew();
2| cloudTable.ExecuteBatchAsync(tableBatchOperation);
3| stopwatch.Stop();
4| log.WriteLine("Committed " + tableBatchOperation.Count + " records " + " in " + stopwatch.Elapsed.TotalSeconds + " seconds.");