这个问题不太可能帮助任何 future 的访客;它只与一个小地理区域、一个特定时刻或一个非常狭窄的情况相关,而这些情况通常不适用于互联网的全局受众。如需帮助使这个问题更广泛地适用,visit the help center .
10年前关闭。
我正在编写一个使用 COM 库的应用程序。我有一个类库,它封装了对 COM 库的调用并添加了更多功能。最终这将作为 Windows 服务运行。现在我使用 Winforms 测试工具对其进行测试。
当测试工具创建类库时,一切似乎都工作正常。当我尝试将其作为服务运行时,问题就开始了。它创建正常,甚至对 COM 的第一次调用也正常。然后,COM 对象引发我处理的事件,并响应事件中的结果,我调用 COM 库中的另一个函数。在我从测试工具运行它但作为服务运行时抛出异常的情况下,该函数被成功调用:
System.InvalidCastException occurred Message="Unable to cast COM object of type '' to interface type ''. This operation failed because the QueryInterface call on the COM component for the interface with IID '{350ADD2A-18CB-4D9C-BE28-48D53F14E6FB}' failed due to the following error: The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))."
我可以看到存在线程问题。在测试工具案例中,所有这些调用都发生在主线程上,而在 Windows 服务的情况下,Service OnStart 覆盖和 COM 事件处理程序都在不同的线程上。我一直在尝试不同的事情但没有成功。有什么建议么?
最佳答案
某些 COM 组件只能由 STA 线程访问。如果你的情况是这样,
您可以像这样在 STA 线程中完成 COM 工作:
RunInSTAThread( () => com_object.DoSomething() );
private static void RunInSTAThread(ThreadStart thread_start)
{
Exception threadEx = null;
ThreadStart wrapped_ts = () =>
{
try
{
thread_start();
}
catch (Exception ex)
{
MethodInfo preserveStackTrace =
typeof(Exception).GetMethod("InternalPreserveStackTrace",
BindingFlags.Instance | BindingFlags.NonPublic);
preserveStackTrace.Invoke(ex, null);
threadEx = ex;
}
};
Thread thread = new Thread(wrapped_ts);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
if (threadEx != null)
{
throw threadEx;
}
}
对于您的情况,这可能不是线程(每次调用的新线程)的最佳用途,但它是一个起点。
关于c# - 尝试调用 COM 库时服务引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/778104/