C# 为什么异步CTP的性能很差?
我真的不明白为什么wait和async不能提高代码的性能 虽然我对此表示怀疑,但我认为编译器应该重写我的方法,以便下载可以并行进行。。。但这似乎并没有发生。 我确实意识到wait和async不会创建单独的线程;然而,操作系统应该以视差方式进行下载,并在原始线程中调用我的代码——不是吗 我是否正在使用async并错误地等待?正确的使用方法是什么 代码:C# 为什么异步CTP的性能很差?,c#,.net,async-ctp,async-await,C#,.net,Async Ctp,Async Await,我真的不明白为什么wait和async不能提高代码的性能 虽然我对此表示怀疑,但我认为编译器应该重写我的方法,以便下载可以并行进行。。。但这似乎并没有发生。 我确实意识到wait和async不会创建单独的线程;然而,操作系统应该以视差方式进行下载,并在原始线程中调用我的代码——不是吗 我是否正在使用async并错误地等待?正确的使用方法是什么 代码: 我可能误读了您的代码,但看起来您正在启动一个后台线程来执行异步读取,然后立即阻塞,等待它完成。代码的“异步”部分实际上不是异步的。试试这个: st
我可能误读了您的代码,但看起来您正在启动一个后台线程来执行异步读取,然后立即阻塞,等待它完成。代码的“异步”部分实际上不是异步的。试试这个:
static async Task<int> SumPageSizesAsync(string[] uris)
{
int total = 0;
var wc = new WebClient();
var tasks = new List<Task<byte[]>>();
foreach (var uri in uris)
{
tasks
.Add(wc.DownloadDataTaskAsync(uri).ContinueWith(() => { total += data.Length;
}));
}
Task.WaitAll(tasks);
return total;
}
我可能是错的-异步的东西是新的,我不是100%熟悉它-但类似的同步版本的时间似乎证明了我。克里斯的回答几乎是正确的,但引入了竞争条件,并同步阻止了所有任务 一般来说,如果有wait/async可用,最好不要使用任务延续。另外,不要使用WaitAny/WaitAll-异步等价物是WhenAny和WhenAll 我会这样写:
static async Task<int> SumPageSizesAsync(IEnumerable<string> uris)
{
// Start one Task<byte[]> for each download.
var tasks = uris.Select(uri => new WebClient().DownloadDataTaskAsync(uri));
// Asynchronously wait for them all to complete.
var results = await TaskEx.WhenAll(tasks);
// Calculate the sum.
return results.Sum(result => result.Length);
}
陛下因此,我想合乎逻辑的问题是,正确的方法是什么?编辑以添加我认为它应该如何工作。再说一次,可能完全错了。谢谢!虽然我认为wait的全部要点是将方法的其余部分改为continuation-passing样式,而异步CTP的全部要点是消除对委托/lambda的大量管道的需要。。。那么,这与BeginInvoke和诸如此类的东西有什么不同呢?至少从.NET 2.0开始,我们就已经有了这些东西。是的,但在您的情况下,wait在循环中,因此循环不能继续,直到循环中的wait语句返回为止。至少这是我读到的。我不认为wait语句可以实现fork/join并行。。。所以wait挂起整个方法并返回调用方,即使该方法的某些部分可能是可并行的?噢,这看起来更干净了谢谢
static async Task<int> SumPageSizesAsync(string[] uris)
{
int total = 0;
var wc = new WebClient();
var tasks = new List<Task<byte[]>>();
foreach (var uri in uris)
{
tasks
.Add(wc.DownloadDataTaskAsync(uri).ContinueWith(() => { total += data.Length;
}));
}
Task.WaitAll(tasks);
return total;
}
{
var start = Environment.TickCount;
await SumPageSizesAsync(uris);
Console.WriteLine("Async CTP: {0} milliseconds", Environment.TickCount - start);
}
static async Task<int> SumPageSizesAsync(IEnumerable<string> uris)
{
// Start one Task<byte[]> for each download.
var tasks = uris.Select(uri => new WebClient().DownloadDataTaskAsync(uri));
// Asynchronously wait for them all to complete.
var results = await TaskEx.WhenAll(tasks);
// Calculate the sum.
return results.Sum(result => result.Length);
}