我刚刚继承了一个使用生产者 - 消费者模式的c#4.0 WinForms应用程序(基本上只是一个小仪表板)。我的消费者任务(字面意思是System.Threading.Tasks.Task)正在处理队列中的数据。当用户想要关闭应用程序时,生产者(TCP套接字服务器)立即停止。但是,队列可能不是空的,因此我需要为用户提供立即退出的选项,或者在使用者任务处理完所有排队数据后立即退出。如果用户想要等待消费者任务完成,则UI自然需要保持响应。我遇到的问题是,由于退出应用程序的代码驻留在“退出”按钮的单击事件处理程序中,我可能需要等待消费者任务完成,而我在单击事件处理程序中。简而言之,事件处理程序包含这个(非常难看的)代码:
// loop while there is still data in the queue
while (QueuedData.Count > 0)
{
Application.DoEvents(); // UI is semi-responsive but with a lot of CPU utilization)
}
// the queue is empty so now exit the application
任何人都可以建议一种实现此功能的替代方法,以便我不会陷入UI线程上的事件处理程序中的紧密循环中吗?在这一点上启动另一个线程/任务以处理此检查然后从该线程关闭应用程序是否有任何意义?非常感谢!
答案 0 :(得分:0)
您可以在同一队列中排队退出任务[通过“退出”按钮] - 队列完成后,将调用Exit处理程序。
如果您愿意,可以在此期间将UI更新为“退出待处理...”。
答案 1 :(得分:0)
处理关闭事件,取消它,向关闭表单的任务添加延续。
答案 2 :(得分:0)
也使用像你所提到的那样的循环可能是CPU密集型的。为什么不完全使用Observer模式,以便:
订阅者将侦听更新并在BlockingCollection(或任何其他阻止集合)中将其排队
另一个后台线程将等待上述队列中的项目并在其出现时对其进行处理
关机时:
您停止发布到队列;
您可以查看队列中有多少项目并通知GUI,以便用户可以选择等待强行关闭(