我遇到了这个问题中描述的问题: Unable to cast COM object of type exception 这表现为错误:
无法将“System.__ComObject”类型的 COM 对象转换为接口类型“IMyInterface”。此操作失败,因为 IID 为“{GUID}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口
我的 WPF 应用程序正在调用最终调用 COM 对象的 .NET 库。这工作正常,但它在主线程上运行并阻塞 UI。当我生成一个新线程并从中调用库时,我收到了该错误。其他问题的这些解决方案都不适合我。我试图了解运行时如何加载类型信息,但不能在线程之间共享它。
我知道 WPF 应用程序是 STA,我知道这意味着在线程之间移动的任何对象都将被 COM 编组。我不明白如何说“这是一个 COM 对象,它的 GUID 是这个”的类型信息可以在 AppDomain 中,但第二个线程无法访问。
加载的类型信息在哪里?它是在 AppDomain 中,还是在每个线程中?无论如何,我怎样才能让线程共享类型信息?我怎样才能解决这个问题?
我读过这个: http:
//www.codeproject.com/Articles/9190/Understanding-The-COM-Single-Threaded-Apartment-Pa
和这个:http:
//msdn.microsoft.com/en-us/ library/ms973913.aspx#rfacomwalk_topic10
和一堆其他关于 COM 互操作的东西,但没有帮助我修复它。
根据 Hans Passant 的回答,我正在第二个 STA 线程中创建我的库对象:
var thread = new Thread(delegate()
{
var aeroServer = new AeroServerWrapper(Config.ConnectionString);
var ct = new CancellationToken();
aeroServer._server.MessageReceived += ServerMessageReceived;
aeroServer.Go(@"M:\IT\Public\TestData\file.dat", ct);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
我知道,如果事件未能触发,我可能需要调用 Application.Run() 来启动消息队列,但我并没有走那么远:它在尝试创建 COM 对象时立即崩溃。AeroServerWrapper 位于一个单独的 DLL 中,它调用第二个 DLL,最终尝试实例化 COM 对象。
任何提示或文章将不胜感激。我想按原样解决这个问题:我的 B 计划是将库包装在控制台应用程序中,从 UI 生成控制台应用程序,并通过命名管道从中获取状态消息。这会起作用,但它看起来很难看。