异步等待让我的任务,而慢task.Start()运行它们快 [英] async await makes my tasks slow while task.Start() runs them fast

查看:141
本文介绍了异步等待让我的任务,而慢task.Start()运行它们快的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我运行10K的任务,每个发送一批数据到Azure存储表。

I am running 10k tasks which each send a batch of data to an Azure Storage Table.

如果我用下面异步第一种方法是等待运行的任务返回任务的执行速度很慢,并从几秒钟越来越慢攀达10,100秒等。

If I use the first method below with async await that returns running tasks the tasks execute really slow and increasingly slower from a couple of seconds climbing up to 10, 100 seconds etc.

如果我用下面的第二个方法返回新的正在运行的任务,他们跑得还真快!只是一个非常几十每个任务毫秒。

If I use the second method below that returns new running tasks they run really quickly! Just a very few tens of ms per task.

为什么会出现如此巨大的差异吗?我缺少什么?

Why is there such a huge difference here? What am I missing?

在我创建任务结束时,我做了一个简单Task.WaitAll(allTask​​s.ToArray())。

At the end of my task creation I do a simple 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

aftger

推荐答案

由于当您使用的await 你实际上是在等待的结果,因此,如果您阻塞 ExecuteBatch ,它不会结束,直到 ExcecuteBatchAsync 结束。

Because when you use await you are actually "awaiting" the result, so if you block on ExecuteBatch, it won't end till ExcecuteBatchAsync ends.

在另一方面, ExecuteBatch2 不等待任何东西。即使你在 ExecuteBatch2 响应块中, ExecuteBatchAsync 操作是并行和 ExecuteBatch2推出结束,尽管 ExecuteBatchAsync 启动任务仍在运行。

In the other hand, ExecuteBatch2 does not "await" anything. Even if you block on the ExecuteBatch2 response, the ExecuteBatchAsync operation is launched in parallel and ExecuteBatch2 ends, despite of the task launched by ExecuteBatchAsync is still running.

更新:

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.");

在第一种方法,因为你在等待,你不会得到与行#3,直到2号线两端。

In the first method, because you are awaiting, you won't get to line #3 until line #2 ends.

然而,在你的第二个方法:

However in your second method:

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()你可能会得到同样的结果比第一种方法。

You will get from line #2 to line #3 immediately, because ExecuteBatchAsync is happening in parallel, nothing is making the thread block for a result. If you do cloudTable.ExecuteBatchAsync(tableBatchOperation).Wait() you will probably get the same result than in the first method.

这篇关于异步等待让我的任务,而慢task.Start()运行它们快的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆