async await使我的任务变慢,而task.Start()快速运行它们

时间:2014-11-28 12:51:45

标签: c# azure async-await azure-table-storage

我正在运行10k个任务,每个任务都将一批数据发送到Azure存储表。

如果我使用async await下面的第一个方法返回正在运行的任务,那么任务执行的速度非常慢,而且从几秒钟内爬升到10,100秒等就会越来越慢。

如果我使用下面的第二种方法返回新的运行任务,它们会很快运行!每项任务只需几十毫秒。

为什么这里有这么大的差异?我错过了什么?

在我的任务创建结束时,我做了一个简单的Task.WaitAll(allTask​​s.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

1 个答案:

答案 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(),你可能会得到与第一种方法相同的结果。