C#-Compact Framework Windows CE-GUI线程阻止高优先级线程

C#-Compact Framework Windows CE-GUI线程阻止高优先级线程,c#,C#,我遇到了一个问题,我有一个用C#编写的Windows CE compact framework应用程序,其中我将主GUI线程设置为正常优先级,将通信线程设置为高于正常优先级,以获得尽可能接近伪实时的性能。我遇到的问题是,在允许编辑配置数据之前,我在一个按钮处理程序中运行一个循环,将配置数据从文件加载到GUI。这大约需要2-3秒才能完成。在事件处理程序中发生此阻塞时,我的高优先级通信线程被阻塞。如果线程同步到位,则没有锁。通信线程与GUI线程没有依赖关系 这就是我生成通信线程的方式:

我遇到了一个问题,我有一个用C#编写的Windows CE compact framework应用程序,其中我将主GUI线程设置为正常优先级,将通信线程设置为高于正常优先级,以获得尽可能接近伪实时的性能。我遇到的问题是,在允许编辑配置数据之前,我在一个按钮处理程序中运行一个循环,将配置数据从文件加载到GUI。这大约需要2-3秒才能完成。在事件处理程序中发生此阻塞时,我的高优先级通信线程被阻塞。如果线程同步到位,则没有锁。通信线程与GUI线程没有依赖关系

这就是我生成通信线程的方式:

        MbWorkerThread = new Thread(MbPollingThread);
        MbWorkerThread.IsBackground = true;
        MbWorkerThread.Priority = ThreadPriority.AboveNormal;
        MbWorkerThread.Start();
这是一个MTA应用程序。此外,我还尝试在GUI事件处理程序中使用Thread.Sleep(1)来让位于优先级更高的线程,但它不起作用。我还尝试使用信号向优先级更高的线程屈服,但这不起作用。唯一有效的方法是在事件处理程序中加载配置时,将Application.DoEvents()放入循环中。这只是一个测试,因为我不想在我的代码中加入Application.DoEvents(),以使其工作,因为我知道Application.DoEvents()是危险的

我的理解是,主GUI线程是一个前台线程,但仍然是一个线程。此外,我将通信线程设置为后台线程,以便在主线程退出时终止它

我什么都试过了,在问这个问题之前我一直在网上搜索

任何帮助都将不胜感激


顺便说一句——我想用一个窗体计时器,但我知道它是在GUI线程中运行的,所以这不会有帮助。我考虑过另一个线程,但我真的不知道如何通过Invoke处理GUI更新。

您的程序从
Main()
开始,您通常在那里调用
Application.Run(new MyForm())
Application.Run()
实现标准的Windows消息泵,它处理来自操作系统和其他应用程序的消息,包括用户输入、进程间通信、重绘请求等

GUI事件(如按钮单击)通过该线程进行调度。如果在事件处理程序中执行长时间运行的工作,则不会处理其他消息

Application.DoEvents()
阻止调用线程,并等待处理所有挂起的消息。如果
DoEvents
Sleep(1)
没有帮助时帮助您的通信线程,那么我怀疑您的通信线程与GUI/消息泵线程之间存在依赖关系


即使不是这样,阻止GUI线程也不是一个好主意。使用
ThreadPool.QueueUserWorkItem()
将文件加载移到后台,并使用
Invoke
BeginInvoke
将结果封送回UI

BeginInvoke代替Invoke解决了这个问题。谢谢你的回复。

你的建议正是我所倾向的,所以谢谢你。我只是不明白一个被认为优先级较高的线程怎么会被优先级较低的主线程阻塞。我想不出我在comm线程中做的任何事情都依赖于GUI线程。你说有一种我不知道的隐性依赖?我假设消息pump dispatch正在阻塞进程中的其他线程。我开始认为这是windows ce的一个限制。不确定,再次感谢您的回复。通讯线程正在做什么。。。网络、串行、使用COM组件或其他库?不要在按钮处理程序中加载文件,而是尝试睡眠(5000)并检查通信线程在这段时间内是否有任何进展。我试过在1毫秒到1000毫秒之间的任何地方睡觉,我没有试过5000毫秒,但我希望通信线程能有一些活动。我不知道在串口中使用的基本组件,但我假设它是文件访问,就像你在C++中那样。我将尝试一下,看看我是否能找到一些依赖于UI线程的东西。再次感谢。嗯,我想我已经发现我确实对UI线程有依赖性。经过更多的研究和理解,我有一种感觉,我正在调用Control.Invoke到不同的表单,这些表单都是在GUI线程上创建的,这导致了调用comm线程的阻塞。由于GUI线程正在运行事件处理程序,comm线程将到达invoke,invoke将消息发布到GUI线程并阻止它,直到它被处理为止,这反过来又造成了我所看到的问题。有时,当你发现一些本应简单易懂的东西时,你会觉得自己像个傻瓜。因此,由于GUI线程拥有消息泵,Application.DoEvents允许处理Control.Invoke发布的消息,因此允许comm线程继续。因此,明天我将测试我的修复程序,使用BeginInvoke而不是Invoke,并将文件读取移动到另一个线程以减少GUI线程上的负载。我很确定这就是问题所在。我不会回答我自己的问题,直到我验证它是否有效。再次感谢你为我指引了正确的方向。