Reputation: 700
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
Upvotes: 0
Views: 2145
Reputation: 35965
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.
Upvotes: 2