c# - Task.StartNew Parallel.ForEach 不等待

标签 c# .net async-await task-parallel-library

我有这个代码:

await Task.Factory.StartNew(
    () => Parallel.ForEach(
        urls,
        new ParallelOptions { MaxDegreeOfParallelism = 2 },
        async url =>
        {
           Uri uri = new Uri(url);
           string filename = System.IO.Path.GetFileName(uri.LocalPath);

           using (HttpClient client = new HttpClient())
           using (HttpResponseMessage response = await client.GetAsync(url))
           using (HttpContent content = response.Content)
           {
               // ... Read the string.
               using (var fileStream = new FileStream(config.M_F_P + filename, FileMode.Create, FileAccess.Write))
               {
                   await content.CopyToAsync(fileStream);
               }
           }
        }));

MessageBox.Show("Completed");

它应该处理超过 800 个元素的列表,但它不会等待下载和文件写入完成。 事实上,他开始下载和写入,显示消息,然后在后台继续下载...... 我需要并行和异步下载很多文件,但我必须等待所有文件下载完毕。这段代码有什么问题?

最佳答案

Parallel.ForEach不适用于异步。它需要一个 Action但为了等待异步方法,它需要获得 Func<Task> .

您可以使用 TPL 数据流的 ActionBlock那是在考虑异步的情况下构建的。您给它一个委托(delegate)(异步或非异步)来执行每个项目。您可以配置 block 的并行性(如果需要,还可以配置有限的容量)。然后将您的项目发布到其中:

var block = new ActionBlock<string>(async url => 
{
    Uri uri = new Uri(url);
    string filename = System.IO.Path.GetFileName(uri.LocalPath);

    using (HttpClient client = new HttpClient())
    using (HttpResponseMessage response = await client.GetAsync(url))
    using (HttpContent content = response.Content)
    {
       // ... Read the string.
       using (var fileStream = new FileStream(config.M_F_P + filename, FileMode.Create, FileAccess.Write))
       {
           await content.CopyToAsync(fileStream);
       }
    }
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 } );

foreach (var url in urls)
{
    block.Post(url);
}

block.Complete();
await block.Completion;
// done

关于c# - Task.StartNew Parallel.ForEach 不等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34843224/

相关文章:

javascript - 在 Map() 的条目上使用 Promise.all

c# - 无法在 C# 中反序列化 XML - InvalidOperationException

c# - SQL LIKE 语句或 C# foreach 检查?

c# - ASP .Net MapRequestHandler 慢

c# - 如何正确实现 TAP 方法?

c# - 如何调整图像控件上的图像大小?

python - 属性错误: 'generator' object has no attribute 'connect' Pydle,异步

c# - Assembly.LoadFrom 在包含 MFC 的 cpp/CLI DLL 上失败

c# - 如何检查程序是否是第一次运行?

asynchronous - 如何实现轮询异步 fn 的 Future 或 Stream?