MTA单元中的.NET STA Com对象

MTA单元中的.NET STA Com对象,.net,multithreading,com,rsa,marshalling,.net,Multithreading,Com,Rsa,Marshalling,目前我正在一个站点(MVC)上工作,它大量使用ajax从响应缓慢的异步资源请求数据 但是我有一个问题,每个请求都必须首先得到授权,授权的一部分是通过执行Server.CreateObject(“Rsacookieapi.RSACookie”).GetUserName()来获取当前的RSA用户名。问题是,这个特定的com对象不在MTPartments上运行,只在StatPartments上运行(它们不提供任何可选的.net组件,因此我们必须使用这个组件),因此CreateObject失败 通过大量

目前我正在一个站点(MVC)上工作,它大量使用ajax从响应缓慢的异步资源请求数据

但是我有一个问题,每个请求都必须首先得到授权,授权的一部分是通过执行Server.CreateObject(“Rsacookieapi.RSACookie”).GetUserName()来获取当前的RSA用户名。问题是,这个特定的com对象不在MTPartments上运行,只在StatPartments上运行(它们不提供任何可选的.net组件,因此我们必须使用这个组件),因此CreateObject失败

通过大量研究,我已经通过创建一个自定义路由处理程序来解决这个问题,该处理程序在STA中执行控制器上下文(相当于在webforms上do ASPCOMPAT=TRUE),但这带来了一个进一步的问题,当从STA中执行控制器上下文时,我无法再创建异步控制器方法

所以我开始思考,如果我可以在STA中创建COM对象,并以某种方式创建一个委托/代理给它,这样就可以从MTA访问它,那么一切都会很好

作为概念证明,我有一个全局变量myComObject,我通过在STA请求(/StaController/Index)中执行CreateObject来填充它

然后,我尝试从MTA请求(/MtaController/Index)访问MyMobject

好消息是,这是可行的。似乎clr正在为我处理所有编组

所以我开始编写一些代码,在STA中生成一个新线程,但问题是我仍然需要将HttpContext.Current.Server(HttpServerUtilityBase)传递给线程,当我调用.CreateObject时,线程只会在.Server对象的MTA上执行它

我希望这有意义?澄清:

  • 我不希望我的任何控制器或操作在STA上执行
  • 我想在STA上创建该对象,然后从所有其他MTA访问该对象
  • 我真诚地希望有人有一个建议

    问候

    Karl

    选项1:使用Tlbimp创建部件。 您是否尝试过使用Tlbimp.exe为零部件创建部件,并使用该部件?文件中说,这会导致“性能差”。但这是由于所需的编组,这与您在这里尝试执行的操作相同

    AspCompat属性强制页面在STA模式下执行。如果省略了兼容性标记,并且在页面上引用了STA组件,则运行时会引发异常如果使用Tlbimp.exe将STA组件转换为程序集,则运行时不会检测到该组件使用STA模型,也不会引发异常,但您的应用程序可能会性能不佳

    选择2:撒谎。 如果您只需将注册更改为“两者”,则在您的场景中它可能运行良好。这取决于对象和使用方式

    如果您每次都使用一个新对象,并立即使用Marshall.ReleaseComObject处理该对象,这样您就不会从另一个线程重复使用它,那么就不会有问题

    (STA意味着只能从一个线程调用该对象。COM将通过在具有不同线程模型的单元之间编组来保证共享对象,因此您可以假设单元中的所有对象都与线程模型兼容。不过,您也可以自己提供该保证通过不共享对象和不从任何其他线程调用对象)

    要做到这一点,只需进入注册表中的
    HKEY\U CLASSES\U ROOT\CLSID\{guid}
    并将ThreadingModel键更改为“两者”

    然后进行压力测试