2
我正在讀一些有關異步&等待的博客,特別是Scott's blog。我有一個下面的代碼示例,它可能會下載一個URL列表。爲了簡化事情並使時序合理和可重複,我用一個Task.Delay等待呼叫取代了真實的下載代碼。異步等待(再次)在lambda
第一個代碼在lambda表達式中沒有異步等待對,而第二個代碼沒有。這兩個代碼都可以編譯,並且兩個時間點都相同(約1秒)。
1.)哪種方法是正確的方法?
2.)lambda中的等待異步對會花費更多嗎?
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);
}
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;
}
有沒有另外一種方式來「直觀地」看到差異?例如。查看IL代碼? – alpinescrambler 2014-11-05 00:07:06
@alpinescrambler:是;由編譯器生成的代碼是非常不同的。 – 2014-11-05 06:48:38