2016-07-20 3 views
5

У меня есть код VB6, мне нужно медленно перейти к .NET. Для некоторых из них требуются звонки в Интернет. Я делаю веб-вызов из .NET dll, и когда это будет сделано, он запускает событие. Я обрабатываю событие в VB6. Теперь это отлично работает на моей тестовой машине и большинстве пользовательских машин, но некоторые пользователи получают последовательный крах программы когда-то вокруг, когда событие запускается.Как безопасно запускать асинхронный код и события в .NET, чтобы VB6 мог его обрабатывать?

Я думаю, что это проблема с резьбой. Итак, как я должен обрабатывать потоки на стороне .NET? Отсутствует контекст синхронизации, когда вызывается код .NET, и я думаю, что это может быть проблемой. Как я могу получить операцию async обратно в вызывающий поток VB6? Мой код VB6 - это STA, и я читал, что все будет автоматически подключаться к потоку VB6 через COM, но, возможно, это было неправильно? Я не совсем понимаю, что делать, если это действительно проблема с потоками.

Мне не удалось найти шаблон, на котором компьютеры столкнулись с проблемой сбоя, а какие нет.

+2

Да, вы должны поднять это событие в потоке, который вызвал ваш конструктор. Вам нужен SynchronizationContext, вы можете легко получить его из формы Winforms. Одного достаточно, это не должно быть видно, просто прочитайте его свойство Handle, и это хорошо. –

+1

Хмм, как я могу получить это из формы VB6? Я не открываю какие-либо формы в .NET. – bzuillsmith

+2

Вы пытались отделить и сравнить .Net frameworks на возможных целевых машинах? хотя Microsoft заявляет о полной обратной совместимости в недавних версиях каркаса .Net, которые я нашел не раз, это утверждение является в основном чистым конным дерьмом. – Stavm

ответ

2

Так что позже я обнаружил, что был дезинформирован, и он не работал почти на всех машинах пользователя, кроме нескольких машин разработчика. Проблема заключалась в том, что файл .tlb не создавался и не регистрировался.

Кажется, что если вы запускаете события из основного потока, все в порядке. Но если вы стреляете события асинхронно есть только два пути вы можете заставить его работать без сбоев:

  1. Вы можете вернуть его обратно в основной поток, возможно, через SynchronizationContext из формы.
  2. Вы можете запустить событие из любого потока и позволить ему автоматически перенаправляться на поток STA VB6, но для него требуется дополнительная информация tlb, которая отсутствует в реестре, если вы просто зарегистрируете DLL без опции tlb. Этот параметр хорош, если вы не проходите ни один поток пользовательского интерфейса, который устанавливает SynchronizationContext.

Обратите внимание, что если вы используете безрежимный COM, для опции 2 требуется элемент comInterfaceExternalProxyStub в манифесте вашей сборки. См. Пример question and answer here.