Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
642 views
in Technique[技术] by (71.8m points)

c# - async await makes my tasks slow while task.Start() runs them fast

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

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?

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

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.

UPDATE:

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

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

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...