如何确保在IIS中使用相同的线程来执行代码?

时间:2008-09-04 19:11:20

标签: vb.net multithreading iis dll

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

(对Rob Walker的回应)

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

5 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

我认为您需要查看使用处理DLL调用的包装线程,并处理序列化。

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

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

答案 2 :(得分:0)

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

通过这种方式,您可以控制调用DLL的线程以及线程的生命周期。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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