为什么从 .NET BackgroundWorker 线程调用非托管代码会影响 UI?
我在 .NET 2.0 BackgroundWorker
线程中运行了一系列长时间运行的操作。 当我调用位于引用程序集中的非托管代码时,UI 将被冻结,直到调用完成。
为什么是这样? 我不应该从 BackgroundWorker
线程进行这些调用吗?
是的,它是一个 COM 组件,但我不确定如何判断它是否是 STA 以及其含义/分辨率是什么。 我对该组件进行了多次调用,但只有在长时间运行的组件中,我才注意到 UI 变得无响应。
这些调用从服务器检索数据。
I have a long running series of operations in a .NET 2.0 BackgroundWorker
thread. When I make a call to unmanaged code located in a referenced assembly the UI is frozen until the call completes.
Why is this? Should I not be making these calls from the BackgroundWorker
thread?
Yes, it is a COM component but I'm not sure how to tell if it's STA or not and what the implications/resolution are/is. I make several calls to that component but it is only the long-running ones where I notice the UI becoming unresponsive.
These calls retrieve data from a server.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您在问题中有 COM 标记 - 您是否正在调用 COM 组件? 它是 STA 组件吗? 如果是这样,它很可能会以某种方式编组回来在 UI 线程上完成其工作。 我承认我距离成为 COM 方面的专家还有很长的路要走,但如果这就是问题所在,我也不会感到惊讶。
如果您从显式创建的新线程进行调用,会发生什么情况?
You've got the COM tag in the question - are you calling into a COM component? Is it an STA component? If so, it may well be marshalling back to do its work on the UI thread somehow. I'll readily admit I'm a long way from being an expert on COM stuff, but I wouldn't be surprised if that were the problem.
What happens if you make the calls from a new thread which you've explicitly created?
是的,而且,所有非托管代码都会发生这种情况还是只是特定组件或 API 会发生这种情况? 如果是特定的,那么该非托管代码在做什么?
Yes and also, does this happen with all unmanaged code or just a specific component or API? If a specific one, what is that unmanaged code doing?
另外,您可以简单地注释掉BackgroundWorker 中当前的代码(您正在正确运行RunWorkerAsync...)并在那里进行睡眠。 如果您的 GUI 变得无响应,则说明有些问题,否则就是您正在调用的代码,正如 Jon 指出的那样,COM 可能就是这种情况。
Also, you could simply comment out your current code in the BackgroundWorker (you are running RunWorkerAsync right...) and put a sleep in there. If your GUI becomes unresponsive something's not right, otherwise it's the code you are calling as Jon points out could be the case with COM.