【问题标题】:Legacy code performance issue - Create UIControl on second thread, not only alter it遗留代码性能问题 - 在第二个线程上创建 UIControl,而不仅仅是更改它
【发布时间】:2014-12-15 18:21:24
【问题描述】:

我继承了一个 winforms 应用程序。它使用呈现文档和照片的第三方封闭控件......它只有用于打开文档的同步方法。问题是我的客户正在处理非常大的文档(在 2GB 的区域!!!)并且打开这些文档真的“阻塞”了 UI 线程......这很糟糕......

常识会让您认为“只需将其卸载到后台线程”,但问题是“如何”!看,要更改控件(因为调用“打开”会导致它被更改)我需要 Invoke 它,这会导致代码再次在 UI 线程上运行...锁定它...

所以我把桌子倒过来了。如果不是在主线程上创建控件并将其传递给后台线程进行处理,我可以在后台线程上创建控件,加载它(避免这种方式的跨线程异常),完成后,馈送它到主线程?!?

现在我需要知道如何明确地处理对另一个线程的控制,而不仅仅是暂时...

【问题讨论】:

  • 必须设计控件来支持这一点,而且可能并非如此。听起来它的核心设计只是有缺陷。唯一真正好的解决方案是解决这个问题,如果没有能力打开它,你可能无法做到这一点。
  • 是的。听起来完全像是“我们只有一把锤子和一个不称职的工匠,所以我们将这个控件设计成看起来像钉子”。绝对不在大文件上使用它 - 或者他们接受了这个问题。与供应商交谈,他们将不得不解决这个问题。从头到尾都没有办法做到这一点。
  • 请注意,从后台线程调用 Invoke 一次不需要占用 UI 线程很长时间。如果加载任务是无 GUI 的,并且只需要更新 GUI 中的进度条,则使用 Invoke 更新进度条不会将 UI 占用很长时间,因此 UI 将保持响应.最大的麻烦将是如何正确地将加载的文档从后台线程传递到 GUI 线程——我不太了解的问题(与处理器缓存和内存可见性有关)但 @Servy 可能会。
  • (我上面的评论依赖于有一个无 GUI 的数据模型,一旦数据加载完成,该模型可用于填充第三方控件。如果“加载”真的只是添加的过程数据直接从文件到第三方控件,然后在后台线程上加载不会给你带来太多好处,除了你会有许多对 Invoke 的简短调用,GUI 线程可以在这些调用之间处理其他事件,这意味着你的 GUI 将保留至少有点反应。)

标签: c# multithreading


【解决方案1】:

我不确定这是否可行,但您可以尝试:

  • create a new form on a secondary thread(此表单将托管您的精美控件)
  • 从此辅助 UI 加载文档。它将被阻止,但您可以将其隐藏并仅显示 在主 UI 上加载消息。
  • 作业完成后,将“工作”转移到主 UI 和主线程。

这只是一个想法。

【讨论】:

  • 我测试了它,我可以说它可以工作(至少有一个按钮)。在辅助表单上,我添加了一个带有 public 修饰符的按钮。加载辅助表单后,我将按钮转移到主表单。
【解决方案2】:

你要求做的事情是不可能的。 Winforms 控件的线程亲和性是在创建该控件时确定的,并且不能更改。

最好的解决方案是不使用该控件。我怀疑它所做的任何事情都不能被其他人正确和胜任地实施。

如果您可以在第二个 STA 线程中运行一个完全不同的窗口,那么这将是下一个最佳选择。加载文档时,该特定窗口仍将被冻结,但至少您的主 UI 仍然可以。请注意,您不应尝试在同一窗口中混合和匹配来自不同线程的控件;这会导致各种头痛。

最后,作为一个完整的 hack,您可以考虑继续在后台线程中调用此 Open() 方法,尽管该控件由主 UI 线程拥有。在公认的摇摇欲坠的假设下,该控件将真正尝试访问 UI 组件本身的唯一时间是在 Open() 方法操作的最后,您可以继续捕获抛出的 InvalidOperationException,并使用作为文件加载完成的信号。然后在主 UI 线程中使控件无效。

我认为最后一个建议的可能性不超过 50/50。这将取决于控件对加载的数据实际执行的操作,如果它是某种复合控件,它依赖于实际获取其加载结果并将其复制到控件作为Open() 方法的一部分,那部分可能会失败,并且控件不会正确初始化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多