Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么异步CTP的性能很差?_C#_.net_Async Ctp_Async Await - Fatal编程技术网

C# 为什么异步CTP的性能很差?

C# 为什么异步CTP的性能很差?,c#,.net,async-ctp,async-await,C#,.net,Async Ctp,Async Await,我真的不明白为什么wait和async不能提高代码的性能 虽然我对此表示怀疑,但我认为编译器应该重写我的方法,以便下载可以并行进行。。。但这似乎并没有发生。 我确实意识到wait和async不会创建单独的线程;然而,操作系统应该以视差方式进行下载,并在原始线程中调用我的代码——不是吗 我是否正在使用async并错误地等待?正确的使用方法是什么 代码: 我可能误读了您的代码,但看起来您正在启动一个后台线程来执行异步读取,然后立即阻塞,等待它完成。代码的“异步”部分实际上不是异步的。试试这个: st

我真的不明白为什么wait和async不能提高代码的性能

虽然我对此表示怀疑,但我认为编译器应该重写我的方法,以便下载可以并行进行。。。但这似乎并没有发生。 我确实意识到wait和async不会创建单独的线程;然而,操作系统应该以视差方式进行下载,并在原始线程中调用我的代码——不是吗

我是否正在使用async并错误地等待?正确的使用方法是什么

代码:


我可能误读了您的代码,但看起来您正在启动一个后台线程来执行异步读取,然后立即阻塞,等待它完成。代码的“异步”部分实际上不是异步的。试试这个:

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);
}