我正在处理一个严重的数据绑定的Win.Forms应用程序,我发现了一些奇怪的行为。该应用程序具有单独的I/O线程,通过异步web请求接收更新,然后将其发送到主/ GUI线程,以处理和更新应用程序范围的数据存储(这又可以将数据绑定到各种GUI-元素等)。 Web请求另一端的服务器需要定期请求或会话超时。与从非GUI线程显示MessageBox相关的问题
我已经通过处理线程的问题等几个尝试的解决方案走了,我观察到以下行为:
如果我使用Control.Invoke从我发送更新/ O-线程到主线程,此更新会导致MessageBox显示主窗体的消息泵停止,直到用户单击确定按钮。这也阻止了I/O线程继续最终导致服务器超时。
如果我使用Control.BeginInvoke从I/O线程(或多个)发送更新主线程的主窗体的消息泵不不停止,但如果更新的处理导致了一个消息是如图所示,该更新的其余部分的处理将暂停,直到用户单击确定。由于I/O线程继续运行,并且消息泵继续处理消息,因此可以在消息框完成之前调用几个用于更新的BeginInvoke。这导致无法接受的失序更新。
I/O线程将更新添加到阻塞队列(非常类似于Creating a blocking Queue<T> in .NET?)。 GUI线程使用Forms.Timer定期应用阻塞队列中的所有更新。该解决方案既解决了阻塞I/O线程的问题,又解决了更新的顺序性问题,即直到完成前一个更新才会开始。但是,性能成本很低,并且在显示更新时引入延迟,这在长期内是不可接受的。我希望主线程中的更新处理是事件驱动的而不是轮询。
所以对我的问题。我应该怎么做这:
- 避免阻塞I/O线程
- 保证更新完成了序列
- 保持主消息泵运行,同时显示一个消息框,为的结果更新。
更新:请参见下面
问题:必须在用户单击messageBox上的“确定”后才更新GUI,或者只能通知他们已发生更新,例如通过多行文本框中的消息? – Asher 2010-04-08 10:19:56
它必须是一个弹出窗口,但我不确定它是否需要模态。我可以创建自己的非模态弹出窗口。 – 2010-04-08 11:14:41