2013-11-25 9 views
1

У меня есть проект ASP.NET Web Api, где мне нужно использовать VB6 Com dll. У меня есть один контроллер, где я создаю объект класса из com dll и использую этот объект в своем действии. Кажется, все работает, когда я вызываю это действие с ок. 2000-2500 нить, но когда я запускаю его из нескольких потоков, то я получаю эту ошибку при создании объекта COM экземпляра:ASP.NET Web Api с COM-dll

Creating an instance of the COM component with CLSID from the IClassFactory failed due to the following error: 800401f7 (or 800a01b8). 

Я обнаружил, что компоненты ком работают в режиме Thread STA, но ASP.NET Web Api в MTA Thread mode, но я не знаю, вызвало ли это проблему, потому что я не мог найти ничего, как изменить режим STA в проекте ASP.NET Web Api.

Я использую сам Host ASP.NET Web Api, и я размещаю его в службе Windows. Когда я остановлю службу и запустил ее снова, я снова могу отправить ca. 2500 потоков.

EDIT: Я создал темы в приложении образец окна, как это:

for (int i = 0; i < threadsCount; i++) 
     { 
      Task task = Task.Factory.StartNew(() => { 
       for (int j = 0; j < loopCount; j++) 
       { 
        SendRequest(); 
       } 
      }); 
     } 

EDIT2: Возможно COM-объект не выделяется, потому что в диспетчере задач можно видеть, что ручки растет, и я получаю эту ошибку когда он имеет 2000+ ручек. Я называю Marshal.ReleaseComObject, поэтому я не уверен, что может быть неправильным.

+0

это не будет работать, ваша машина будет блокировать тезисы потоков, максимальные потоки дефолт по умолчанию, я думаю, что это ограничено ядрами вашего процессора. – IamStalker

+0

Но у меня нет проблем, если я не вызываю объект com. –

+0

Я не думаю, что вы делаете это параллельно. – IamStalker

ответ

2

Я бы не стал рекомендовать изменение вашей модели потоковой передачи вашего проекта ASP.NET Web Api.

Режим STA добавит уровень синхронизации между вызовами к различным компонентам фреймворка. (см. Could you explain STA and MTA?)

Поскольку вы добавляете этот уровень синхронизации, вы можете столкнуться с блокировками из-за этой синхронизации.

Я думаю, что лучше порезать нити.

2500+ нить не будет эффективной, попробуйте рассмотреть ThreadPool (http://msdn.microsoft.com/en-us/library/system.threading.threadpool%28v=vs.110%29.aspx)

Вы получите производительность, поскольку это позволит сократить издержки присвоения/переключения Threads на CPU.

Что касается ошибки: если вы создаете 2500+ экземпляров COM-компонента, могут возникнуть проблемы с распределением памяти. Особенно, если это сторонняя COM-библиотека DLL, вы не можете быть уверены, что выделенная память освобождена. Скорее всего, COM-компонент не разработан или не проверен на такое количество экземпляров. Шансы утечки памяти большие. и т.д. и т.п.

Так что мой совет:

Палка с моделью MTA, рубили на резьбе.

+0

Я использовал столько потоков только для тестирования, но это веб-приложение api будет работать все время как служба Windows, поэтому проблема также возникает, когда я вызываю действие, например. 200 раз с только 10 потоками.Может быть, есть какой-то предел где-то или что-то еще? Извините, но я новичок в C#. –

+0

Где именно вы создаете все эти темы? В WebApi? В службе windows? Или вы отправляете 200+ запросов в API? Другое дело: когда вы используете COM, обязательно вызовите 'Marshall.ReleaseComObject', если вы закончите с интерфейсом с запросом. См. Http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject%28v=vs.110%29.aspx – Stefan

+0

Я делаю 200 запросов к API из примера приложений Windows. Я создаю в своем классе ApiController экземпляр объекта com, например _obj = new Class(); в конструкторе, но я не вызывал ReleaseComObject, поэтому я попробую это. –