Странные вещи, происходящие с компонентом COM в веб-сервисе - PullRequest
0 голосов
/ 21 ноября 2011

Я получаю странное поведение для веб-службы .NET 2.0, которая использует устаревший COM-объект.Вот сценарий:

Есть 2 клиентских приложения, первое приложение вызывает мой веб-сервис, когда получает уведомление об обновлении.Второе приложение опрашивает и извлекает записи из моего веб-сервиса, использует мой веб-сервис для определения необходимости обновления, а затем снова вызывает веб-сервис для удаления обработанной записи.Если запись требует обновления, вторая сообщает первой, что что-то было обновлено, и первое приложение запускает событие, которое, в свою очередь, вызывает мой веб-сервис.

Вот как это выглядит.Приложение № 2:

client.Records <- WebService.GetRecords()

for each record in Records
  client <-> WebService.IdentifyRecord(record)
  Notify Application #1 that it's time to call my web service.
  client -> DeleteRecord()

Приложение № 1: получает уведомление от приложения № 2 и вызывает WebService.PerformUpdates (...)

Таким образом, все это может происходить параллельно.То есть мы можем перейти к следующей записи, пока выполняется метод PerformUpdates.

Извините за длинное подробное описание установки (я знаю, что оно запутанное, я не могу сказать по этому вопросу) ... вотпроблема: Мои методы IdentifyRecord и PerformUpdates вызывают COM-компонент, который, в свою очередь, использует ADODB.Recordset.В моем журнале я замечаю, что выдается несколько исключений, но не для каждой записи, может быть, 1 из 10 выдает исключение.Исключение происходит в компоненте COM (к сожалению, я не могу получить источник, поэтому об изменении его не может быть и речи).Иногда это ошибка BOF / EOF для набора записей, в других случаях это ошибка ссылки NULL.И настоящая странность случается, когда я смотрю на трассировку стека.Допустим, это мой код:

adodbRecordSet.MoveFirst()
while not (adodbRecordSet.Eof)
  rowInDataTable = myDataTable.NewRow()
  rowInDataTable.BeginEdit()
  rowInDataTable("ID") = adodbRecordSet.Fields("ID").Value
  rowInDataTable("Name") = adodbRecordSet.Fields("Name").Value
  rowInDataTable("Address") = adodbRecordSet.Fields("Address").Value
  --> rowInDataTable("OtherInfo") = adodbRecordSet.Fields("OtherInfo").Value <-- HERE is where the exception occurs!!!
  rowInDataTable("YetMoreInfo") = adodbRecordSet("YetMoreInfo")
  rowInDataTable.EndEdit()
  adodbRecordset.MoveNext()
  myDataTable.AddRow(rowInDataTable)
next

В случае исключения объекта NULL это происходит внутри коллекции Fields.

Не могу не подумать, действительно ли это былоОшибка EOF / BOF или что-то еще, тогда это проявилось бы в первой строке («ID»)?

Итак, все, что я могу предположить, это то, что что-то происходит с COM и параллельными вызовами в Интернет.имя_службы.Если я вызываю веб-сервис поочередно (каждый метод за другим), он работает как чемпион.Но если клиент вызывает веб-сервис, используя событие, вот что происходит.

Может кто-нибудь пролить свет на то, что происходит ???

Спасибо!

1 Ответ

1 голос
/ 21 ноября 2011

Если вы взаимодействуете с COM из ASP.NET, вам необходимо знать кое-что о модели потоков COM для компонента, с которым вы взаимодействуете. Вот статья с полезной информацией .

Имейте в виду, что какую бы модель потоков ваш COM-компонент не поддерживал, это всего лишь утверждение от разработчика. Многопоточность сложна, и многие устаревшие компоненты COM не понимают ее правильно.

Если у вас нет доступа к источнику или поддержки COM-компонента, вам может потребоваться использовать блокировку для сериализации доступа.

...