I was reading a few blogs about async & await, particularly that of Scott's blog . I have a code sample below, which presumably downloads a list of URLs. To simplify things and make the timings reasonable and repeatable, I replaced the real download code with a Task.Delay awaitable call.
The first code doesn't have an async-await pair inside the lambda expression, while the second one has. Both codes compile, and both timings come out the same (around 1 second).
1.) Which method is the right way to do this?
2.) Will the await async pair inside the lambda cost more?
private async void Button_Click(object sender, RoutedEventArgs e)
{
// Capture the UI synchronization context for use later
var ui = TaskScheduler.FromCurrentSynchronizationContext();
// SAMPLE 1 , is this the right way?
var items = Enumerable.Range(1, 100).Select(i => i.ToString()).ToList();
var sp = new Stopwatch();
sp.Start();
// NO await async pair in lambda
var results1 = await Task.WhenAll(
items.Select(item => DownloadFileAsync(item)));
sp.Stop();
var testResult = string.Format("Single await: {0} seconds"
, sp.Elapsed.TotalSeconds);
// SAMPLE 2, or this way?
var items1 = Enumerable.Range(1, 100).Select(i => i.ToString()).ToList();
var sp1 = new Stopwatch();
sp1.Start();
// WITH await async pair in lambda
var results = await Task.WhenAll(items1.Select(async item =>
await DownloadFileAsync(item)));
sp1.Stop();
var testResult1 = string.Format("Double await: {0} seconds",
sp1.Elapsed.TotalSeconds);
// show results
await Task.Factory.StartNew(() =>
{
MessageBox.Show(testResult + System.Environment.NewLine + testResult1);
}, CancellationToken.None, TaskCreationOptions.None,
ui).ConfigureAwait(false);
}
and
private async Task<string> DownloadFileAsync(string uri)
{
//using (var client = new WebClient())
//{
// string data = await
client.DownloadStringTaskAsync(uri).ConfigureAwait(false);
// return data;
//}
await Task.Delay(1000).ConfigureAwait(false);
return uri;
}
Both of them are roughly equivalent. The first one is slightly more efficient.
For the purposes of this question, you can think of
await as "unwrapping" a task, andasync as "wrapping" a method in a task.The first example uses a lambda expression to define a function with the signature Task<string> F(string). The function defined by the second example has the same signature. The difference is that
DownloadFileAsync directlyIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With