我有一个问题,我有一个用C#编写的Windows CE compact framework应用程序,其中我将主GUI线程设置为正常优先级,并将一个通信线程设置为高于正常优先级,以获得接近伪实时性能的性能。我遇到的问题是在一个按钮处理程序中,我运行一个循环来将配置数据从文件加载到GUI中,然后才允许对其进行编辑。这大约需要2-3秒才能完成。当事件处理程序中发生这种阻塞时,我的更高优先级的通信线程正在被阻塞。没有锁,线程同步在适当的位置。通信线程不依赖于GUI线程。
这就是我如何产生我的通信线程:
MbWorkerThread = new Thread(MbPollingThread);
MbWorkerThread.IsBackground = true;
MbWorkerThread.Priority = ThreadPriority.AboveNormal;
MbWorkerThread.Start();它是一个MTA应用程序。此外,我还尝试在图形用户界面事件处理程序中使用Thread.Sleep(1)来让位于更高优先级的线程,但它不起作用。我还尝试使用信号来让位给更高优先级的线程,但这不起作用。唯一有效的方法是在事件处理程序中加载配置时将Application.DoEvents()放入循环中。这只是一个测试,因为我知道Application.DoEvents()很危险,所以我不想在我的代码中使用Application.DoEvents()来让它工作。
我的理解是,主GUI线程是前台线程,但仍然是一个线程。此外,我还将通信线程设置为后台线程,以便在主线程退出时将其终止。
我什么都试过了,在问这个问题之前,我已经在互联网上搜索了无数次。
任何帮助都将不胜感激。
附注:我想过表单计时器,但我知道它是在GUI线程中运行的,所以这不会有什么帮助。我想过另一个线程,但我真的不知道如何通过Invoke来编组GUI更新。
发布于 2011-08-05 04:26:06
BeginInvoke而不是Invoke修复了这个问题。谢谢你的回复。
发布于 2011-08-04 03:05:41
您的程序从通常调用Application.Run( new MyForm() )的Main()开始。Application.Run()实现了标准的Windows消息泵,它处理来自操作系统和其他应用程序的消息,包括用户输入、进程间通信、重绘请求等。
GUI事件,如Button click,是通过这个线程调度的。如果在事件处理程序中执行长时间运行的工作,则不会处理其他消息。
Application.DoEvents()阻塞调用线程,并等待处理所有挂起的消息。如果DoEvents帮助你的通信线程,而Sleep(1)没有,那么我怀疑你的通信线程和图形用户界面/消息泵线程之间存在依赖关系。
即使不是这样,阻塞GUI线程也不是一个好主意。使用ThreadPool.QueueUserWorkItem()将加载的文件移到后台,使用Invoke或BeginInvoke将结果编组回UI。
https://stackoverflow.com/questions/6930774
复制相似问题