使用来自一个特定线程的对象

时间:2009-04-12 13:35:42

标签: c# multithreading com

我有一个COM对象,我在dotnet中使用,我必须在同一个线程上调用它。问题在于,从概念上讲,整个计划中存在多种用途。确保在这个特定的后台线程上调用此对象的所有用法的最佳方法是什么?示例代码会很棒。

3 个答案:

答案 0 :(得分:2)

您可以在程序启动时启动一个线程,它应该处理所有COM交互。然后你可以有一个包装器对象,它将任务推送到一个队列上供线程处理。

包装器可以包含同步代码,以便向调用者隐藏多线程(即将包装的调用作为同步方法公开)。

如果这是一个WinForms项目,也许你可以通过简单地使用GUI线程和Control.Invoke方法来偷工减料。 (但是如果通话需要很长时间,那么这不是一个好主意,因为你会在通话期间阻止用户界面)。

答案 1 :(得分:0)

如果您可以在STA下使用该对象,则可以在同一个线程上调用它 为此,您需要在Main上添加STAThreadAttribute 唯一的问题是所有 COM对象将以这种方式处理。

答案 2 :(得分:0)

为了做到这一点,你必须首先建立一种方法来获得特定线程的特定调用。 .Net有几个内置的机制来做这个,但我发现最简单的是SynchronizationContext类。 WinForms和WPF都为运行消息循环的任何线程建立SynchronizationContext实例。

所以我会...

  • 为对象启动新线程
  • 创建一个隐藏的WinForms或WPF窗口并运行它
  • 抓取该线程的SynchronizationContext
  • 在该线程上创建COM对象

现在您有了COM对象的位置以及将调用回到正确线程的方法。下一步是创建代理对象。该对象应具有COM对象的所有方法(并且可能只是实现COM接口)。然后,它将使用同步上下文调用每个方法并将调用代理到真实的COM对象。

public class Foo {
  private ComFoo _com;
  private SynchronizationContext _context;
  public void Bar() { 
    _context.Send(notUsed => _com.Bar(););
  }
}