【发布时间】:2011-01-11 15:30:19
【问题描述】:
我有一个冻结界面的 c# .NET 多线程应用程序。不寻常的是,除非我让系统空闲足够长的时间以启动屏幕保护程序(这需要我重新输入密码才能重新获得对系统的访问权限),否则界面不会冻结。当界面再次可见时(在我成功输入密码后)界面被锁定。只要我不让屏保启动,界面就不会死机。
我应该指出,我有两个不同的可执行文件访问同一个 dll,无论我使用哪个应用程序访问 DLL,都会出现这个问题。这似乎暗示问题出在 DLL 中,因为这两个应用程序完全不同 (C++/MFC) 和 (C#/.NET),除了它们与 DLL 的关系。
两个 exe 执行与 DLL 交互的类似步骤。他们调用 dll 来设置串行端口通信,在 DLL 中打开一个状态窗口,在 DLL 中启动一个线程来监视通信端口,然后在主应用程序中启动一个线程来监视 dll 中的堆栈。
当 DLL 中的线程从通信端口获取数据时,对其进行解析并将其结果放入堆栈,然后通过委托发布到状态窗口。当 exe 中的线程看到堆栈中的数据时,它会在主窗口中输出数据,同样使用委托。
我发现,如果我将代码添加到 DLL 中的线程,使其每 30 秒调用一次 Application.DoEvents(),接口将冻结大约 30 秒,然后像正常一样恢复活动。 我认为某些东西阻塞了主线程并强制 DoEvents() 触发似乎打破了锁,但我不知道是什么导致了这个锁。
这个问题出现在我的开发机器和测试机器上。
我已尝试将数据输出完全删除到 DLL 内的状态窗口,但这没有任何区别。
我从事多线程编程多年,从未见过这样的事情;所以任何建议将不胜感激。
谢谢。
【问题讨论】:
-
在调试器中暂停冻结的 UI 并查看调用堆栈。
-
您是否尝试过仅从非 UI 线程调用 DLL 方法并编组到 UI 线程?
-
这可能并不完全有帮助,但是您是否打开了任何在屏幕保护程序启动时会发生的省电功能? (我认为这可能会使端口进入休眠状态。)
-
不管是什么,
Application.DoEvents都不是答案。 -
似乎无法让它在我的开发中失败。今天机器。
标签: c# multithreading