Все события COM заблокированы после завершения BackgroundWorker (в AppDomain) - PullRequest
1 голос
/ 23 февраля 2012

У меня есть программа, которая обрабатывает несколько экземпляров класса, каждый из которых имеет собственный экземпляр COM-объекта DLL.Чтобы убедиться, что каждый класс использует отдельный экземпляр, я создаю класс с доменом приложения:

_objectDomain = AppDomain.CreateDomain("somename")
Dim item As ObjectType
item = CType(_objectDomain.CreateInstanceAndUnwrap(GetType(ObjectType).Assembly.FullName, _
GetType(ObjectType).FullName), ObjectType)
'do a bunch of stuff to item
_itemList.Add(item)

Позже я инициализирую соединение, используемое в объекте COM:

For Each obj In _itemList
    obj.Connect()
Next

И каждый Connect выполняет:

Private Sub Connect()
    Try
        _item.Connect("SQL", TableName)
        If Not _item.Initialized Then _
            Throw New Exception("Connection was not initialized.")
        _item.StartMirroring() 'this watches specified files to see if they've been updated
    Catch Ex As Exception
        Alert("Could not connect to database.")
    End Try
End Sub

Пока домены приложений работают параллельно, каждый вызов obj.connect () ожидает завершения _item.Connect (), прежде чем двигаться дальше, поэтому инициализация может занять некоторое время, если яесть несколько предметов.Поэтому я пытаюсь использовать BackgroundWorker для одновременного запуска:

Public Sub Connect()
    _itemWorker = New BackgroundWorker
    AddHandler _temWorker.DoWork, AddressOf ConnectWorker
    AddHandler _itemWorker.RunWorkerCompleted, AddressOf StartMirror
    _itemWorker.RunWorkerAsync()
End Sub

Однако, если я сделаю это таким образом, события из _item больше не будут срабатывать после запуска RunWorkerCompleted.Функция .Connect () вызывает много событий, все из которых успешно запускаются внутри и без BackgroundWorker, но как только я попадаю в StartMirror, события больше не генерируются из COM (я должен получить событие MirrorStateChanged при вызове .StartMirroring (),но ничего не происходит).Если я уберу фонового работника и отпущу их в последовательности, они будут подняты без проблем.Я могу в любом случае вызывать события в своем классе.

Согласно эта ссылка :

События BackgroundWorker не маршалируются через границы AppDomain.Не используйте компонент BackgroundWorker для выполнения многопоточных операций в нескольких доменах приложений.

Однако я не считаю, что это является проблемой по двум причинам:

  1. BackgroundWorker содержится в AppDomain для этого экземпляра класса и не связывается ни с каким другим AppDomain, кроме основного потока (посредством событий)
  2. События по-прежнему запускаются в BackgroundWorker, но не после его завершения

Я попытался повторно связать обработчики после завершения Worker и создать BackgroundWorker на уровне основного приложения, но оба безуспешно.Почему объект COM перестает вызывать события?Я все еще могу взаимодействовать с ним просто отлично, но, к сожалению, COM (третий патри, с закрытым исходным кодом) общается в основном через события, поэтому я не могу просто проверить связь с ним, чтобы спросить, активно ли он проверяет зеркала.Если мне придется выполнять большие процессы в последовательности, это нормально, потому что они будут иметь очень ограниченное использование, но я бы предпочел запускать их в фоновом режиме, если это вообще возможно.

...