【问题标题】:Is there a way for one .NET Control to contain another Control which is owned by a seperate GUI thread?有没有办法让一个 .NET 控件包含另一个由单独的 GUI 线程拥有的控件?
【发布时间】:2009-11-03 23:33:31
【问题描述】:

我正在考虑创建一个选项卡式界面,该界面在选项卡式或 MDI 界面中具有用户控件(可能由插件开发人员编写)。这些插件控件可能会无意中冻结它们的 GUI 线程,我希望它们不会影响其他选项卡中的用户控件。就像谷歌浏览器为每个标签创建一个进程一样;但在这种情况下,只是线程。

或者甚至是 MDI 接口,其中子 MDI 表单由不同的线程拥有?

我发现虽然我可以同时运行多个 GUI 线程,但表单级别是它们必须分开的地方。任何解决方法/想法?

对于那些说不需要的人,我称之为废话。出于安全和 UI 原因,Google 的 Chrome 浏览器在单独的进程中运行标签。我只是想复制这种行为。当编写用户控件的人是糟糕的插件开发人员时,这一点很重要。

【问题讨论】:

  • 不要让用户控件冻结他们的 GUI 线程。见鬼!
  • freeze their gui thread?你为什么想做这个?是设计使然还是由于限制?
  • 我认为人们误解了你的意图。我认为您不是在问如何冻结其他选项卡上的用户控件,我认为您是在问如何防止用户控件在您的应用程序忙于处理长时间运行的请求时冻结应用程序。如果这是真的,您可能需要改写您的问题。
  • @senfo:我就是这么想的!
  • 谢天谢地,你不能这样做,也没有理由这样做。

标签: c# .net multithreading user-interface


【解决方案1】:

不,不可能按照您描述的方式执行此操作。拥有/关联到另一个 GUI 线程的控件不能直接包含在拥有/关联到不同线程的控件中,这样它的绘制函数在另一个线程上运行。

【讨论】:

  • 不喜欢。如果他们需要该死的,他们应该召集电话! :)。在 WPF 中怎么样?
  • @TheSoftwareJedi,同样适用于 WPF :(。至少对于所有可变类型而言。少数不可变/可冻结类型可能是可能的。不过,还不足以确切地说出来。跨度>
  • 你为什么“不喜欢”?您有什么用例只能通过您的方法解决而无法通过调用另一个线程上的方法来解决?
  • @Ed 这个应用程序允许用户安装我无法控制的插件。如果这些插件导致 GUI 延迟 - 我的应用程序受到指责。这与 Chrome 问题非常相似。我宁愿看到当标签变坏时谷歌显示的“Aw Snap”,然后让整个应用程序变坏。当给定的插件死机/锁定时,如果整个应用程序没有死机,那么责任在谁身上就更清楚了。不要这么快跳到脑震荡。我不是白痴。
  • @TheSoftwareJedi:如果插件不必符合任何特定的预先存在的 API,一种方法是不给插件对 UI 线程的任何访问权限,而是让它们绘制到屏幕外缓冲区。性能不会很好,但您可以更好地防止它们对系统造成严重破坏。如果您可以接受性能损失,您甚至可以将插件降级到它们自己的应用程序域或进程。
【解决方案2】:

解决这种情况的正确方法是编写不在 UI 线程上执行长时间运行任务的 UserControl。如果控件正在阻塞并等待某个计算任务,请修复那个。使该任务在后台运行,并让控件显示一些非计算密集型内容,直到完成。如果该任务冻结,控件将冻结在“我正在等待...”状态,但它不会侵入 UI 的其余部分。

如果您使用无法修复的第三方控件,那么,用 Jay-Z 的不朽名言来说,我为您感到难过,儿子。

【讨论】:

  • 不,真的不是,在这种情况下,恐怕你无能为力。
【解决方案3】:

在大多数情况下,控件不应执行任何处理。它们的目的是提供用户和应用程序之间的交互性。例如,从数据库中获取数据并将其呈现给用户并不是按钮的工作。话虽如此,但愿您在控件事件处理程序中进行处理,例如 Button 控件上的 Click 事件。在您的事件处理程序中,您可以通过在后台线程中处理任务来防止 UI 出现“挂起”。 BackgroundWorker 在这些情况下通常很有用。

我建议阅读线程。 The Microsoft® .NET Framework Application Development Foundation book 有一个关于线程的部分(即使没有阅读其他认证书籍,我至少建议所有 .NET 开发人员阅读这本书)。请记住不要从子线程更新 UI。如果您不熟悉这种方法,请阅读 how to make a thread-safe call to Windows controls 上的示例。

【讨论】:

  • 我不需要阅读线程。我写了很多多线程软件。我知道最初的问题是可能的——但在 .NET 中可能不行。我允许用户动态加载插件,并将它们放到一个新选项卡上。因此,应该隔离所述插件。我不是在寻求关于线程和控制开发的技巧——只是关于如何解决所述问题的建议。
【解决方案4】:

您应该从不同的角度看待整个问题,而不是拥有或拥有不同的 GUI 线程。为什么要冻结与选项卡的子控件关联的线程?如果它确实冻结了并且其他所有东西也都开始了,那么除了线程之外,这并不是从头开始的。

JaredPar 指出的是正确的,但这并不意味着您无法实现您想要的。我假设您希望在选项卡中运行的内容继续运行/停止,而不会影响其他控件和用户体验。

我以前在一个复杂的 WinForm 应用程序中做过。以下是一些可能会给您带来更多见解的阅读材料:
Threading out tasks in a C#.NET GUI
Thread and GUI
Updating GUI from Other Threads in C#
Advanced Techniques To Avoid And Detect Deadlocks In .NET Apps

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    • 2016-10-18
    • 1970-01-01
    • 2021-02-12
    相关资源
    最近更新 更多