【问题标题】:Why does the event not fire until after the parallel threads finish?为什么在并行线程完成之前事件不会触发?
【发布时间】:2011-04-25 20:17:17
【问题描述】:

我正在获取项目列表并将它们放入 ListView。这个列表可能很长,所以我使用 Parallel.ForEach() 来处理 ListObjects 的构造。

实例化每个项目后,我在 UI 线程上触发一个事件以将项目添加到 ListView。我的日志记录向我表明,事件正在等待并行任务完成,然后再继续 AddItem 事件。这对我没有帮助。我需要显示器尽快更新,但如果它一直在等待事件,为什么要并行运行?

我不应该为此使用事件吗?通过创建一个委托来保存 UI 回调方法并改为使用它会更好吗?

【问题讨论】:

  • 我已经有一段时间没有写了,但我记得一种创建列表控件的方法,该控件具有项目计数但实际上不包含任何内容。它不是将所有内容都保存在控件中,而是要求其控制器按需填写可见项目的数据。真的很有效。
  • 好的,问题是 Parallel.ForEach 没有在单独的线程上执行,而不是在它启动的线程上执行。所以它正在使用 UI 线程(以及其他两个线程),并且在 Parallel.ForEach 循环完成后完成了任何调度。一旦我将 Parallel.ForEach 放在 Task.Factory.StartNew 中,它就会将 ForEach 放在不同的线程上,并且工作完全按照我认为应该的方式完成。
  • 上面请求的代码:`Task.Factory.StartNew(() => { Parallel.ForEach(FileSystemInfoList, ListItemOptions, (WorkItem) => { //Task Body ItemCreator_DoWork_2(WorkItem); }); }); `(好的,你是怎么做代码标记的?)
  • public void ItemCreator_DoWork_2(ListViewItem) { ...创建专门的 ListViewItem... Task.Factory.StartNew(() => { OnAddItemProgress(new AddItemProgressEventArgs(CurrentPercentage, NewList)); }, CancellationToken。无,TaskCreationOptions.None,uiScheduler); }

标签: c# .net multithreading events parallel-processing


【解决方案1】:

是的,Parallel.ForEach() 的目的是提高填充 ListView 的完成时间。但是您仍然需要等待 ListView 完全加载后才能显示它。

如果您想要在填充时可以查看的内容,您可以尝试ObservableCollection。但是你应该小心;生成的 UI 活动可能会降低应用程序的性能。

【讨论】:

  • 嗯,当我使用 3.5 的 BackgroundWorker 时,我可以很好地引发事件。 BackgroundWorker.ProgressChanged 事件将为我同步回 UI 线程(而不是使用 FromCurrentSynchronizationContext),但这是唯一的区别。而且它仍然没有回答我最初的问题,即为什么事件在触发之前要等待线程完成。我会给你提到的课程一个很好的外观,但这是一个 WinForms 应用程序,我不确定实现 WPF 对象有多容易。它至少给了我一些想法。
  • 虽然 MSDN 页面中给出的示例是 WPF 应用程序,但 ObservableCollection (严格来说)不是 WPF 类。它可以在任何地方使用。
  • 我不知道它等待的确切的技术原因,但是当您考虑它时,它确实是有道理的。使Parallel.For 可行的原因是您的大型任务中隐含的线程安全假设;它假定没有可能干扰完成整个任务的副作用或外部力量。换句话说,你不能在循环运行时直接进入循环。
  • 如上所述,Parallel.ForEach 不会在不同的线程上执行。它包括它在调度中的线程。在新线程上启动任务,然后 Parallel.ForEach 将释放 UI 线程。
【解决方案2】:

这不是您问题的答案,但我认为这可能是获得您想要的结果的改进方法。

我找到了我要找的东西。它是一个 Virtual ListView,也就是 VirtualMode 中的 ListView。

看这里:

http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode.aspx

【讨论】:

    猜你喜欢
    • 2014-09-07
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多