【发布时间】:2011-01-13 17:45:59
【问题描述】:
我有一个冻结界面的 c# .NET 多线程应用程序。不寻常的是,除非我让系统闲置足够长的时间以启动屏幕保护程序(这需要我重新输入密码才能重新获得对系统的访问权限),否则界面不会冻结。当界面再次可见时(在我成功输入密码后)所有窗口都是白色的。我可以看到窗口标题,移动窗口,最小化它们等等,但屏幕没有重新绘制。当我打破所有并进入调试器时,调用堆栈有 Application.Run()、外部代码,然后是“处于睡眠、等待或加入状态”。我在打开的所有四个线程中都设置了断点,它们仍在运行,只是主应用程序的 UI 线程被阻塞。当我查看我的线程列表时,我的主线程和我的四个工作线程现在由我的主线程和 11 个工作线程组成。我没有打开这么多线程,所以它必须是串口类。
现在让我描述一下我的程序。
我的主应用程序允许用户从串行端口收集和监控数据。我已经通过以下方式实现了这一点。当需要连接时,在主应用程序上按下一个按钮,该按钮调用 DLL 中的一个函数,该函数打开一个状态窗口,然后启动一个监视串行端口的线程。当该函数返回时,主应用程序会启动一个线程来监控 DLL 中在初始化时创建的队列。当从串行端口接收到数据时,会解析数据,然后更新状态窗口(通过委托)并将数据推送到队列中。当主应用程序工作线程在队列中看到数据时,它会检索它并使用委托将其发布到主应用程序的列表框中。在所有情况下,我都使用 BeginInvoke 来调用这些代表。
我的 DLL 包含两个库,用于它可以与之通信的两种不同类型的设备。
当我连接到两个设备时会出现此问题;因此每个设备有四个工作线程两个。 DLL 本身设置为 comm 对象,因此我可以从 C++/MFC 应用程序和 c# 应用程序轻松访问它,这两个应用程序都使用它。
我发现,如果我将代码添加到 DLL 内的线程,使其每 30 秒调用一次 Application.DoEvents(),接口将冻结大约 30 秒,然后像正常一样恢复活动。我认为某些东西阻塞了主线程并强制 DoEvents() 触发似乎打破了锁,但我不知道是什么导致了这个锁。这不是一个解决方案,只是一些有趣的事情。
如果您有任何建议,我将不胜感激。谢谢。
【问题讨论】:
标签: c# .net multithreading