2009-04-22 104 views
-1

我正在编写使用COM库的应用程序。我有一个类库,将调用包装到COM库中,并添加了一些功能。最终这将作为Windows服务运行。现在我使用Winforms测试工具测试它。尝试调用COM库时服务抛出异常

当类库由测试工具创建时,一切似乎都工作正常。当我尝试将它作为服务运行时,问题就开始了。它创建成功,即使第一次调用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事件处理程序位于不同的线程上。我一直在尝试不同的事情而没有成功。有什么建议么?

+0

您能否提供一些示例代码? – 2009-04-22 16:36:33

回答

1

某些COM组件只能由STA线程访问。如果这是你的, 你可以做你的COM工作在STA线程,像这样的情况:

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; 
      } 
     } 

这可能不是线程的最佳使用您的具体情况(每次调用一个新的线程)但这是一个起点。

+0

@Jeremy Lew:这也完全没有必要。创建RCW时,如果创建发生在非STA线程上,CLR将把对象放置在它自己的线程中。您也不会在STA线程上抽取消息,这是处理STA COM对象时必须的。 – casperOne 2009-04-22 16:42:08

+0

这些都是很好的一点。它仍然不清楚为什么它从Winforms启动时起作用,而不是从服务启动时。 – 2009-04-22 16:49:24

0

Win服务是否与Winforms应用程序在相同的用户帐户下运行?

0

现在已经解决了。我不得不重新安排线程。现在COM对象和所有对它的调用都在同一个线程上,并且没有线程间的问题。 如何在常见情况下处理它仍然不清楚。

-1

我刚刚关闭了项目并重新打开并解决了错误

相关问题