1

我们在 IIS6 中托管的 Web 服务中使用了第三方 dll。问题是一旦这个 dll 被加载到内存中,如果一个与创建它的线程不同的线程试图执行 dll 中的任何代码,就会抛出异常AccessViolationException 。工作进程是多线程的,每次调用 Web 服务都会从池中获得一个随机线程。我们试图从内存中卸载它并在每次需要时重新加载它,但我猜只有前端是 .Net,其余的是非托管的,因此它实际上从未完全从内存中卸载。我们正在使用 VB 和 .Net 2.0。有什么建议么?

(对罗伯·沃克的回应)

我们考虑过创建一个新线程并使用它来调用 dll,但是我们如何让线程坐下来等待调用呢?如何在没有 .Net 3.0 提供的 Dispatcher 类的情况下将调用委托给线程?创建一个隐藏表单并将其放入消息循环中可能会起作用。然后我们可以调用表单的 Invoke() 方法。但是,如果我们在 IIS 托管的 Web 服务中创建表单,我会看到很多问题。

4

5 回答 5

1

我已经阅读了 .net 3.0 中一个名为Dispatcher的类,它允许您将线程放入循环中,然后使用委托调用方法 Invoke() 以使用线程执行方法。但如果您无法更新到 .Net 3.0,此解决方案将不起作用。另一种解决方案是将第三方 dll 托管在服务器上的另一个应用程序中,并使用某种形式的远程处理来访问它。但是您可能仍然对 Remoting 有问题,因为它的行为类似于 IIS,并且还会选择一个随机线程来执行代码。为了解决这个问题,您可以在 dll 周围放置一个包装器,并使用表单的 Invoke() 方法将调用委托给 UI 线程。

于 2008-09-04T19:12:11.180 回答
1

我认为您需要考虑使用处理对 DLL 的所有调用并处理序列化的包装线程。

此线程位于托管线程池之外,因此您可以控制其生命周期。但即使这样也不是万无一失的,除非您可以阻止 IIS 重新启动您的 Web 服务所在的应用程序域。

您还需要担心两个 Web 服务请求同时进入时会发生什么。对 DLL 的每个调用是独立的,还是必须在允许为任何其他请求提供服务之前将与单个 Web 服务请求关联的所有调用组合在一起?

于 2008-09-04T19:24:30.370 回答
0

您可以创建一个托管额外 DLL 的服务。通过远程访问服务,这将调用管理 DLL 的线程。

这样,您就可以控制调用 DLL 的线程以及线程的生命周期。

于 2008-10-06T14:00:39.423 回答
0

您可以在不同的线程中作为不同的实例运行 dll 吗?就像thread1创建了这个第三方dll的一个实例,thread2也这样做了,但是只要thread1不尝试使用thread2的实例,它就不会抛出那个异常?如果是这种情况,.Net 加载后永远不会卸载任何代码,如果您加载程序集然后删除它,它仍然位于该应用程序池中。如果您一次可以创建多个实例,则可以将其加载到您根据请求控制的单独应用程序池中,然后卸载应用程序池。不过性能可能会下降。

于 2008-11-02T03:56:49.280 回答
0

我有点生疏了,但您可以尝试将对 DLL 的调用包装在单线程单元 COM 对象中。这将确保所有调用都通过 COM 对象的 Windows 消息传递线程。我认为您必须在组件服务中的服务器应用程序中注册组件才能执行此操作。

于 2008-10-07T08:02:02.720 回答