Web 服务中的 COM 组件发生奇怪的事情

发布于 2024-12-17 01:26:00 字数 1763 浏览 0 评论 0原文

我发现使用旧版 COM 对象的 .NET 2.0 Web 服务出现一些奇怪的行为。场景如下:

有 2 个客户端应用程序,第一个应用程序在收到更新通知时调用我的 Web 服务。第二个应用程序从我的 Web 服务轮询并检索记录,使用我的 Web 服务来识别它们是否需要更新,然后再次调用 Web 服务以删除已处理的记录。如果记录需要更新,第二个应用程序会告诉第一个记录已更新,第一个应用程序会触发事件,该事件又调用我的 Web 服务。

将其分解如下: 应用#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。在我的日志记录中,我注意到有多个异常被抛出,但并非每条记录都抛出异常,可能十分之一的记录会抛出异常。异常发生在 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 和对 Web 服务的并行调用发生了一些问题。如果我连续调用 Web 服务(每个方法一个接一个),它就会像冠军一样工作。但如果客户端使用事件调用 Web 服务,就会发生这种情况。

任何人都可以阐明发生了什么事吗?

谢谢!

I'm getting some odd behaviour for a .NET 2.0 Webservice that uses a legacy COM object. Here's the scenario:

There are 2 client applications, the first application calls my web service when it receives notification of an update. The second application polls and retrieves the records from my web service, uses my web service to identify if they need updating, and then calls the web service again to delete the processed record. If the record requires an update, the second tells the first that something's been updated and the first application fires the event which in turn calls my web service.

To break it down here's how it looks.
Application #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()

Application #1:
Gets notification from Application #2 and calls WebService.PerformUpdates(...)

So all of this can happen in parallel. That is, we could be moved on to the next record while the PerformUpdates method is executing.

Sorry for the long winded setup description (I know it's convoluted, I have no say in the matter)... here's the problem:
My IdentifyRecord and PerformUpdates methods call a COM component, which in turn uses ADODB.Recordset. In my logging I notice there are multiple exceptions being thrown, but not for every record, may be 1 out of 10 records will throw an exception. The exception happens within the COM component (which, sadly, I can't get source for, so changing it is out of the question). Sometimes it's a BOF/EOF error for the recordset, other times it's a NULL reference error. And the real weirdness happens when I look at the stack trace. Let's say this is my code:

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

In the case of the NULL object exception, it happens inside the Fields collection.

I can't help but think if it really was a EOF/BOF error or whatever, then it would have manifested itself on the first line ("ID")?

So, all I can assume is that there's something going on with COM and the parallel calls to the web serivce. If I call the web service serially (each method after the other), it works like a champ. But if the client calls the web service using the event, this is what happens.

Can anyone shed any light on what's going on???

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

神经暖 2024-12-24 01:26:00

如果您要与 ASP.NET 中的 COM 进行互操作,则需要了解有关与之交互的组件的 COM 线程模型的一些信息。 这是一篇包含一些有用信息的文章

请注意,无论您的 COM 组件声称支持什么线程模型,这都只是开发人员的断言。多线程处理很困难,许多传统的 COM 组件都无法正确处理它。

如果您无权访问源代码或不支持 COM 组件,则可能必须使用锁定来序列化访问。

If you're interoping with COM from ASP.NET, you will need to know something about the COM threading model of the component you're interacting with. Here's an article with some useful info.

Be aware that whatever threading model your COM component claims to support, this is just an assertion from the developer. Multithreading is hard, and many legacy COM components don't get it right.

If you don't have access to the source or support for the COM component, you might have to resort to using locking to serialize accesses.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文