我正在开发一个大量数据绑定的 Win.Forms 应用程序,在该应用程序中我发现了一些奇怪的行为。该应用程序具有单独的 I/O 线程,通过异步 Web 请求接收更新,然后将其发送到主/GUI 线程以处理和更新应用程序范围的数据存储(这反过来可能是数据绑定到各种 GUI 元素, ETC。)。Web 请求另一端的服务器需要定期请求或会话超时。
我已经尝试了几种处理线程问题等的解决方案,并且观察到以下行为:
如果我使用 Control.Invoke 将更新从 I/O 线程发送到主线程,并且此更新会导致显示 MessageBox,则主窗体的消息泵会停止,直到用户单击确定按钮。这也会阻止 I/O 线程继续运行,最终导致服务器超时。
如果我使用 Control.BeginInvoke 将更新从 I/O 线程发送到主线程,则主窗体的消息泵不会停止,但如果更新处理导致显示消息框,则处理其余部分该更新将暂停,直到用户单击“确定”。由于 I/O 线程一直在运行并且消息泵一直在处理消息,因此可能会在消息框完成之前调用多个 BeginInvoke 进行更新。这会导致不可接受的无序更新。
I/O 线程将更新添加到阻塞队列(非常类似于在 .NET 中创建阻塞队列<T>?)。GUI 线程使用 Forms.Timer 定期应用阻塞队列中的所有更新。这个解决方案解决了阻塞 I/O 线程和更新顺序的问题,即下一次更新在前一次完成之前永远不会开始。但是,性能成本很小,并且在显示更新时引入了延迟,从长远来看是不可接受的。我希望主线程中的更新处理是事件驱动的,而不是轮询。
所以我的问题。我应该如何做到这一点:
- 避免阻塞 I/O 线程
- 保证更新按顺序完成
- 保持主消息泵运行,同时显示一个消息框作为更新的结果。
更新:请参阅下面的解决方案