используя объект из одного конкретного потока - PullRequest
2 голосов
/ 12 апреля 2009

У меня есть COM-объект, который я использую в dotnet, и я должен вызывать его всегда в одном потоке. Проблема в том, что концептуально это связано с несколькими вещами на протяжении всей программы. Каков наилучший способ обеспечения того, чтобы все случаи использования этого объекта вызывались в одном конкретном фоновом потоке? Пример кода был бы отличным.

Ответы [ 3 ]

2 голосов
/ 12 апреля 2009

Вы можете запустить поток при запуске программы, который должен обрабатывать все взаимодействия COM. Тогда у вас может быть объект-оболочка, который помещает задачи в очередь для обработки потоком.

Оболочка может содержать код синхронизации, чтобы скрыть многопоточность для вызывающих (т. Е. Представить упакованные вызовы как синхронные методы).

Если это проект WinForms, возможно, вы могли бы сократить углы, просто используя поток GUI и метод Control.Invoke. (Но если вызовы занимают много времени, это не очень хорошая идея, так как вы будете блокировать пользовательский интерфейс во время вызова).

0 голосов
/ 12 апреля 2009

Для того, чтобы сделать это, вы должны сначала установить способ получить конкретный вызов в определенном потоке. .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(););
  }
}
0 голосов
/ 12 апреля 2009

Если вы можете использовать объект в STA, то он может быть вызван в том же потоке.
Для этого вам нужно добавить STAThreadAttribute на ваш Main.
Единственная проблема заключается в том, что ALL COM-объекты будут обрабатываться таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...