【问题标题】:Parallel.For() and Windows message loopParallel.For() 和 Windows 消息循环
【发布时间】:2014-03-04 21:45:33
【问题描述】:

最近我能够将 for 循环转换为 Parallel.For 循环,以加快 WinForms 应用程序初始化中的繁重任务。

不过,当Parallel.For() 运行时,看到一些 OnPaint() 调用通过,我感到非常惊讶。

为什么会这样?有什么方法可以防止 UI 在Parallel.For 期间工作?

编辑:我想节省时间但不更改程序逻辑:我希望Parallel.Forfor 完全一样工作并节省时间。 UI 取决于 for 循环的结果,OnPaint() 失败,因为数据还没有准备好。

【问题讨论】:

  • 阻止 UI 工作很简单。不会在长时间运行期间防止重绘。一些控件具有BeginUpdate/EndUpdateSuspendLayout/EndLayout,这样您就可以开始对许多项目/控件进行操作,而不会在每次修改后引发OnPaint 事件。最好是如果您发布一部分代码,也许您在那里做错了/不是最佳的。您可以通过使控件不可见、通过缓冲区(使用副本)进行修改等来禁用重绘。
  • “我想节省时间但不改变程序逻辑”你不能只将一组同步调用更改为一组异步调用并期望一切正常,因为你是从根本上改变您的应用程序的执行方式。如果你不明白这一点,我建议你先了解线程,然后再尝试将所有内容都设为多线程,而不会意识到潜在的后果。
  • @Ian:你可能是对的,但我对此感到非常惊讶。我怎样才能达到我的要求?也许Parallel.For 不是最好的选择...
  • @Alberto 老实说,您需要重写整个内容。如果您有一些耗时的事情,您不应该只用Parallel.For 替换它,因为它会阻塞呼叫,您需要将其移出到Task 或类似的东西。您的 UI 不应依赖于存在的数据,您的任务应在完成时通知 UI。

标签: c# .net winforms parallel-processing message-queue


【解决方案1】:

您不应该阻塞 UI 线程(阻止 UI 工作)。它使用户不喜欢的应用程序无响应。您应该通过灰显表单并显示进度条来优雅地处理它。

【讨论】:

  • 问题不是阻塞更新 UI 的线程,而是如何阻止 UI 更新。
  • @Trifon 问题被描述为如何“防止 UI 工作”。这不是很具体,但我的观点是,您应该使用用户友好的技术来阻止 UI 工作,而不是通过既不阻止 UI 线程或暂停布局来阻止 UI,
【解决方案2】:

尝试在代表 UI 的表单上调用 this.SuspendLayout()。计算完成后,允许再次使用 this.ResumeLayout() 更新 UI

编辑: 此外,您不应运行从与创建控件不同的线程更新控件的代码。如果这样做,则必须通过Invoke 方法完成。

【讨论】:

  • 这不是“不应该”而是你不能。它会抛出异常。
  • 你“不应该”因为它会抛出异常。但是你总是可以编写抛出异常的代码! :-)
  • 是的,你甚至可以捕捉到这个异常。但是在这种情况下,您的代码将无能为力。绝对没有办法从非 UI 线程执行此操作。 (除了可能非常hackish的东西)。
  • @Andrey 这个“非常杂乱”的事情有据可查:msdn.microsoft.com/en-us/library/757y83z4.aspx
猜你喜欢
  • 2011-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
  • 2021-01-09
  • 1970-01-01
相关资源
最近更新 更多