Как убедиться, что один и тот же поток используется для выполнения кода в IIS? - PullRequest
1 голос
/ 04 сентября 2008

У нас есть сторонний dll, который используется в нашем веб-сервисе, размещенном в IIS6. Проблема заключается в том, что, как только эта DLL загружена в память, исключение AccessViolationException генерируется, если поток, отличный от того, который создал, пытается выполнить любой код внутри библиотеки DLL. Рабочий процесс является многопоточным, и каждый вызов веб-службы будет получать случайный поток из пула. Мы пытались выгружать его из памяти и перезагружать каждый раз, когда нам это было нужно, но я полагаю, что только внешний интерфейс является .Net, а остальное неуправляемо, поэтому он никогда не выгружается из памяти. Мы используем VB и .Net 2.0. Есть предложения?

(Ответ Робу Уокеру)

Мы думали о создании нового потока и использовании его для вызова библиотеки DLL, но как нам заставить поток сидеть и ждать вызовов? Как вы делегируете вызов потоку, не имея класса Dispatcher, предоставленного .Net 3.0? Создание скрытой формы и помещение ее в цикл сообщений может работать. И тогда мы можем вызвать метод Invoke () формы. Но я вижу много проблем, возникающих, если мы создаем форму внутри веб-службы IIS.

Ответы [ 5 ]

1 голос
/ 04 сентября 2008

Я думаю, вам нужно взглянуть на использование потока-оболочки, который обрабатывает все вызовы DLL и занимается сериализацией.

Этот поток находится за пределами пула управляемых потоков, поэтому вы контролируете его время жизни. Но даже это не будет надежным, если вы не сможете предотвратить перезапуск IIS домена приложения, в котором находится ваша веб-служба.

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

1 голос
/ 04 сентября 2008

Я читал о классе в .net 3.0, который называется Dispatcher , который позволяет вам поместить поток в цикл, а затем вызвать метод Invoke () с помощью делегата для выполнения метода с использованием потока. Но это решение не будет работать, если вы не можете обновить до .Net 3.0. Другим решением было бы разместить стороннюю dll в другом приложении на сервере и использовать некоторую форму Remoting для доступа к ней. Но у вас все еще может быть проблема с Remoting, потому что он ведет себя подобно IIS и также выберет случайный поток для выполнения кода. Чтобы обойти это, вы можете поместить оболочку вокруг dll и использовать ее для делегирования вызовов потоку пользовательского интерфейса, используя метод Invoke () в форме.

0 голосов
/ 02 ноября 2008

Можете ли вы запустить dll внутри разных потоков как разные экземпляры? Подобно тому, как thread1 создает экземпляр этой сторонней библиотеки dll, и thread2 также делает это, но пока thread1 не пытается использовать экземпляр thread2, он не будет генерировать это исключение? Если это так, .Net никогда не выгружает какой-либо код после его загрузки, если вы загружаете сборку, а затем удаляете ее, она все еще находится в этом пуле приложений. Если вы можете создать более одного экземпляра одновременно, вы можете загрузить его в отдельный пул приложений, которым вы управляете по запросу, а затем выгрузить пул приложений. Хотя производительность может упасть.

0 голосов
/ 07 октября 2008

Я немного заржавел, но вы можете попробовать обернуть вызовы DLL в однопоточный COM-объект квартиры. Это гарантирует, что все вызовы проходят через поток сообщений Windows COM-объекта. Я думаю, вам придется зарегистрировать компонент в серверном приложении в Службах компонентов, чтобы сделать это.

0 голосов
/ 06 октября 2008

Вы можете создать службу, которая содержит дополнительную DLL. Благодаря удаленному доступу к службе, она будет отправлять вызовы потоку, который управляет DLL.

Таким образом, вы можете контролировать поток, который вызывает DLL, и время жизни потока.

...