【问题标题】:Parallel.Foreach and Task conflictParallel.Foreach 和 Task 冲突
【发布时间】:2014-03-24 11:27:00
【问题描述】:

我正在以并行执行方式将图像上传到云:

// Make a TaskFactory that will use the UI thread's context
var uiFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());

Parallel.ForEach(FinalFileNames,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    path =>
    {
         count++;
         /* Calculate percentage of upload done */
         double iPercentDone = (int)(((float)count / iTotalFiles) * 100);

        // Send the progress report to the UI thread.
        uiFactory.StartNew(() =>
        UploadProgress.Value = iPercentDone;

        LblProgress.Content = count.ToString(CultureInfo.InvariantCulture)
                               + " file(s) uploaded from " + iTotalFiles +
                     " file(s)";
                        }
       });

我面临的问题是,执行此操作时 UI 被阻止。原因似乎在同一个线程中工作..

如果我确实将这个 Parallel.ForEach 包装在“Task.Factory.New”中,那么它会进行异步调用,这不是我的要求。

请告诉我,如何解决 UI 阻塞问题以及不使调用异步。

【问题讨论】:

  • 你试过Application.DoEvents();在每次 foreach 之后?
  • Parallel.ForEach 不适用于图像上传等 IO 绑定任务。一个类似的问题:stackoverflow.com/q/22403856/1768303
  • @AdamHouldsworth - 请参阅编辑..我添加了 uifactory 定义..
  • @Noseratio - 但我在这里没有看到 Parallel.Foreach 有任何问题..我可以将它包装到一个任务中..但问题是我概述的..请告知
  • 您需要在后台工作线程中正确运行您的 parallel.foreach,以避免它阻塞您的 UI 线程

标签: c# asynchronous task-parallel-library parallel.foreach


【解决方案1】:

Parallel.Foreach 从 UI 线程启动时会阻塞 UI 线程直到完成,因此启动的任务将排队但不会运行,直到 UI 线程返回其消息循环。

一种方法是使用Task.Run() 在另一个线程中运行Parallel.Foreach,更好的方法是结合使用async/await 和IProgress<T>

【讨论】:

  • 我认为这是一种异步方法,但我只想在文件上传后更新 UI..如何实现
  • 您不应该在文件上传期间阻塞 UI 线程,这会使应用程序进入“无响应”状态。异步方法是您所需要的。
  • await Task.Run(() => { Parallel.Foreach(...) })
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 1970-01-01
  • 2019-08-27
  • 2012-09-10
  • 2012-08-24
  • 2021-03-06
相关资源
最近更新 更多