代码中的ContextSwitchException问题
我有一个 windows svc,它会进行几次 wmi 调用。这会导致代码运行时间相当长(大约需要两分钟的任务),并且还会冻结 UI 线程(我打算使用后台工作程序作为进度条,并使用另一个线程来执行实际操作)。
目前,在这一切之前,我遇到了上下文切换异常。代码本身可以工作,因为如果我将其粘贴到应用程序本身中,它会成功执行并执行所需的操作。
目前,我已针对此异常关闭了 MDA,并且在长时间运行的任务之前调用 Application.DoEvents()。还需要什么才能摆脱这个异常?
谢谢
I have a windows svc, which makes a couple of wmi calls. This results in fairly long running code (a task which takes about two minutes), and is also freezing the UI thread (I intend to use backgroundworker for the progressbar and another thread for the actual operation).
At the moment, prior to all of this, I get a contextswitchexception. The code itself works, as it executes successfully and does what's required if I paste it within the app itself.
At the moment, I have turned off the MDA for this exception and I am calling Application.DoEvents() just before the long-running task. What else is required to get rid of this exception?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您必须谈论名为 contextSwitchDeadlock 的托管调试助手。这是代码冻结 UI 线程的直接后果。该警告与 COM 相关,它使用 UI 线程的消息循环来封送对非线程安全的 COM 对象的调用。如果 UI 线程没有泵送消息循环,那么这些调用就无法完成。 WMI 使用 COM。
这通常是一个非常现实的问题,这种情况下的死锁很常见。例如,您可以让 UI 线程阻塞在完成作业的工作线程上。循环BackgroundWorker.IsBusy 是一个典型的例子。如果该工作线程正在对单元线程 COM 对象进行 COM 调用,则会导致死锁。工作线程无法完成,因为 UI 线程正在阻塞并且未分派 COM 调用。 UI 线程无法完成,因为工作线程没有取得进展。僵局。
听起来你的情况并不是真正的僵局。警告超时为一分钟,iirc。如果您不介意冻结的用户界面,那么您就不会遇到真正的问题。 UI 线程继续其正常工作后,一切又开始移动。你不会因优雅而得分。
You must be talking about the Managed Debugging Assistant that's called contextSwitchDeadlock instead. It is a direct consequence of your code freezing the UI thread. The warning is associated with COM, it uses the message loop of the UI thread to marshal calls for COM objects that are not thread-safe. If the UI thread isn't pumping the message loop then those calls cannot complete. WMI uses COM.
This is often a very real problem, deadlock in this scenario is pretty common. You could for example have the UI thread block on a worker thread completing a job. Looping on BackgroundWorker.IsBusy is a classic example. If that worker thread is making COM calls on an apartment-threaded COM object then deadlock is the outcome. The worker thread can't complete because the UI thread is blocking and not dispatching the COM call. The UI thread can't complete because the worker thread isn't making progress. Deadlock.
It sounds like it is not a real deadlock in your case. The time-out for the warning is one minute, iirc. If you don't mind the frozen UI then you don't otherwise have a real problem. Everything starts moving again after the UI thread continues its normal job. You won't score any points for elegance.