C# 带有COM dll的ASP.NET Web Api

C# 带有COM dll的ASP.NET Web Api,c#,com,asp.net-web-api,sta,mta,C#,Com,Asp.net Web Api,Sta,Mta,我有一个ASP.NET Web Api项目,我需要使用VB6 Com dll。我有一个控制器,在这里我从com dll创建类的对象,并在我的操作中使用该对象。当我从ca.2000-2500线程调用该操作时,一切似乎都正常,但当我从更多线程运行该操作时,在创建com对象实例时出现以下错误: Creating an instance of the COM component with CLSID from the IClassFactory failed due to the following e

我有一个ASP.NET Web Api项目,我需要使用VB6 Com dll。我有一个控制器,在这里我从com dll创建类的对象,并在我的操作中使用该对象。当我从ca.2000-2500线程调用该操作时,一切似乎都正常,但当我从更多线程运行该操作时,在创建com对象实例时出现以下错误:

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服务上。当我停止服务并再次运行它时,我可以再次发送大约2500个线程

编辑: 我在示例windows应用程序中创建了如下线程:

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

EDIT2:可能com对象没有发布,因为在任务管理器中,我可以看到句柄增长,当它有2000多个句柄时,我会出现这个错误。我调用Marshal.ReleaseComObject,因此我不确定会出现什么问题。

我不建议更改ASP.NET Web Api项目的线程模型

STA模式将在调用框架的各个组件之间添加一个同步层。(见附件)

当您“添加”此同步层时,您可能会因为此同步而遇到死锁

我认为最好是减少线程

2500 +线程将不高效,尝试考虑<代码>线程池< /C> >()< /P> 您将获得性能,因为它将减少为CPU分配/切换

线程的开销

至于错误:如果您创建了2500多个COM组件实例,那么内存分配可能会出现一些问题。尤其是当它是第三方COM DLL时,您无法确定分配的内存是否被适当释放。COM组件没有针对如此多的实例进行设计或测试的可能性很大。内存泄漏的可能性很大。等等等等

因此,我建议:


坚持MTA模型,减少线程。

我只在测试中使用了这么多线程,但此web api将始终作为windows服务运行,因此问题也在于我调用操作时,例如,仅使用10个线程调用200次。也许有什么限制?抱歉,我是c#的新手。你到底在哪里创建这些线程?在WebApi中?在windows服务中?或者您是否向API发布了200多个请求?另一件事:当您使用COM时,如果您使用了查询接口,请确保调用
Marshall.ReleaseComObject
。请参阅:我从示例windows应用程序向API发出了200个请求。我在ApicController类中创建com对象的实例,如_obj=new class();在构造函数中,但我没有调用ReleaseComObject,因此我将尝试此操作。我将ReleaseComObject添加到析构函数中,但没有任何帮助。请确保对从COM组件提取的每个对象调用
封送.ReleaseComObject
。例如,如果com组件使用了一些:
YourComObject.GetSomeOtherObject()
方法,请确保
Marshal.ReleaseComObject
也使用该对象。并非所有函数或
get
方法都需要
Release
,这取决于
ReferenceCount
的内部实现。如果您经常发布到,将会出现一些错误(很容易修复)。如果你没有发布足够的版本,你会遇到难以调试的内存泄漏和各种各样的问题。这不起作用,你的机器会阻止这些线程,最大线程由机器默认,我认为它受到处理器内核的限制。但我不调用com对象时没有任何问题。我认为你不会并行执行。我不知道,我是c#的新手。哦,对不起!我认为默认情况下它受到.net的限制。您应该更改某些内容以允许这样做。