【问题标题】:Calling Parallel.ForEach from a background worker thread从后台工作线程调用 Parallel.ForEach
【发布时间】:2016-10-02 19:52:07
【问题描述】:

我遇到了一个问题,我从 UI 线程调用 Parallel.ForEach,导致 UI 冻结,第一个线程运行速度非常慢,跟不上其余线程。

我在这里读到:Why does this Parallel.ForEach code freeze the program up? 这是一件坏事,然后我发现代码 Task.Factory.StartNew(() => 环绕 Parallel.ForEach 命令以便从后台工作程序运行它。

问题是我不断收到Parallel.ForEach 代码的异常,但除了来自e.MessageOne or more errors occurred 之外没有其他信息。

我做错了什么?

Task.Factory.StartNew(() =>
{
    try
    {
        Parallel.ForEach<ListViewItem>(filesListView.Items.Cast<ListViewItem>(), new ParallelOptions() { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 1.0)) }, (item, state) =>
        {
            Thread.Sleep(100);
            if (CallToStop == true)
            {
                state.Break();
            }

            internalProcessStart(item);
        });
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message);
    }
});

【问题讨论】:

  • 不是打印e.Message,而是打印出完整的异常——只需e.ToString() 就可以了。可能有一个AggregateException,真正的例外将在InnerExceptions 集合中。
  • 这里是完整的错误:imglnk.uk/img?i=JoHlcX
  • 请将错误文本直接放入问题中。不过对我来说看起来很简单 - 您正在尝试从非 UI 线程访问 UI。
  • 问题是使用 UI 线程启动 Parallel.ForEach 会导致 UI 问题并经常冻结。我读到您不应该使用 UI 进行此调用。
  • 我没有说你应该在 UI 线程上调用它。我解释了导致异常的原因,虽然我们不知道确切的位置,因为您没有显示您的处理代码在做什么,但是访问 Items 属性看起来不是一个好主意。基本上,您不应该在任何代码中触摸 UI。

标签: c# multithreading parallel-processing


【解决方案1】:

对于那些有同样问题的人,在任何类型的后台线程中,尽量不要使用任何 UI 依赖变量,例如 Text 或 ListViewItems。要使用这些变量,请在调用后台任务之前将它们放入一个新变量中。然后在任务中使用这个变量。

ListViewItem myIndependentList = filesListView.Items.Cast<ListViewItem>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 2011-06-18
    • 1970-01-01
    相关资源
    最近更新 更多