2013-11-25 56 views
1

我有ASP.NET Web Api項目,我需要使用VB6 COM DLL。我有一個控制器,在那裏我從com創建類的對象,並在我的動作中使用該對象。當我從ca調用該動作時,一切似乎都奏效。 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). 

我發現,COM組件在STA線程模式下運行,但的ASP.NET Web API中MTA線程模式,但我不知道這是否導致了這個問題,因爲我找不到如何在ASP.NET Web Api項目中將模式更改爲STA。

我使用自我託管的ASP.NET Web Api,並將其託管在Windows Service上。當我停止服務並再次運行時,我可以再次發送ca. 2500線程。

編輯: 我創建了樣本窗口應用程序線程是這樣的:

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+線程不會是有效的,儘量考慮ThreadPoolhttp://msdn.microsoft.com/en-us/library/system.threading.threadpool%28v=vs.110%29.aspx

您將獲得的性能,因爲它會降低分配/切換Threads到CPU的開銷。

至於錯誤:如果您創建了超過2500個COM組件實例,則內存分配中可能會出現一些問題。特別是如果它是第三方COM DLL,則無法確定分配的內存是否適合釋放。機會很大,COM組件未針對該實例數量進行設計或測試。內存泄漏的機會很大。等等,等等

所以我的建議:

堅持與MTA模型,削減線程。

+0

我用了很多線程來測試,但是這個web api會一直運行windows服務,所以問題也出現在我調用action 200次,只有10個線程。也許在某處或某處有任何限制?對不起,但我是新來的C#。 –

+0

你究竟在哪裏創建所有這些線程?在WebApi中?在Windows服務?或者您是否向該API發佈了200多個請求?另一件事:當你使用COM時,如果你完成了query-ed接口,一定要調用'Marshall.ReleaseComObject'。請參閱:http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject%28v=vs.110%29.aspx – Stefan

+0

我從示例Windows應用程序向API發出200請求。我在我的ApiController類中創建com對象的實例,如_obj = new Class();在構造函數中,但我沒有調用ReleaseComObject,所以我會試試這個。 –