gpt4 book ai didi

.net - 与从非 GUI 线程显示 MessageBox 相关的问题

转载 作者:行者123 更新时间:2023-12-05 00:06:57 32 4
gpt4 key购买 nike

我正在开发一个大量数据绑定(bind)的 Win.Forms 应用程序,在该应用程序中我发现了一些奇怪的行为。该应用程序具有独立的 I/O 线程,通过异步 Web 请求接收更新
然后它将其发送到主/GUI线程以处理和更新应用程序范围的数据存储(这反过来可能是数据绑定(bind)到各种GUI元素等)。 Web 请求另一端的服务器需要定期请求或 session 超时。

我已经尝试了几种处理线程问题等的解决方案,并且观察到以下行为:

  • 如果我使用 Control.Invoke 将更新从 I/O 线程发送到主线程,并且此更新会导致显示 MessageBox,则主窗体的消息泵会停止,直到用户单击确定按钮。这也会阻止 I/O 线程继续运行,最终导致服务器超时。
  • 如果我使用 Control.BeginInvoke 将更新从 I/O 线程发送到主线程,则主窗体的消息泵不会停止,但如果更新处理导致显示消息框,则处理其余部分该更新将暂停,直到用户单击“确定”。由于 I/O 线程一直在运行并且消息泵一直在处理消息,因此可能会在消息框完成之前调用多个 BeginInvoke 进行更新。这会导致 Not Acceptable 无序更新。
  • I/O 线程将更新添加到阻塞队列(与 Creating a blocking Queue<T> in .NET? 非常相似)。 GUI 线程使用 Forms.Timer 定期应用阻塞队列中的所有更新。该解决方案解决了阻塞 I/O 线程和更新顺序的问题,即下一次更新在上一次完成之前永远不会开始。但是,性能成本很小,并且在显示更新时引入了延迟,从长远来看是 Not Acceptable 。我希望主线程中的更新处理是事件驱动的,而不是轮询。

  • 所以我的问题。我应该如何做到这一点:
  • 避免阻塞 I/O 线程
  • 保证更新按顺序完成
  • 保持主消息泵运行,同时显示一个消息框作为更新的结果。

  • 更新:请参阅下面的解决方案

    最佳答案

    MessageBox 本身会泵送一个消息循环。这当然不会是 Windows 窗体消息循环。一切正常运行,但减去由 Control.BeginInvoke() 发布的委托(delegate)调用请求的调度。只有 Windows 窗体消息循环可以做到这一点。

    当在 UI 线程上调用 MessageBox.Show() 时会发生这种情况。但不是在工作线程上进行时,消息队列是每个线程的属性。如果您可以将 Show 调用委托(delegate)给工作人员,您可能会解决您的问题。

    解决您的问题:

  • 你真的想要相反:工作线程应该阻塞。不阻塞可能会导致重大问题,BeginInvoke 调度队列将无限地填满。一种可能的技巧是计算 BeginInvoke 调用的数量,在委托(delegate)目标中倒计时。使用互锁类。
  • BeginInvoke 目标的执行顺序是有保证的。真正的问题可能与工作线程不同步有关。
  • 在线程上显示消息框。
  • 关于.net - 与从非 GUI 线程显示 MessageBox 相关的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2598450/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com