来自MTA公寓的.NET STA Com对象

时间:2012-03-27 21:43:02

标签: .net multithreading com rsa marshalling

我目前正在开发一个站点(MVC),它使用ajax非常重要地从缓慢响应的异步资源请求数据。

我遇到了一个问题,每个请求都必须首先被授权,并且该授权的一部分是通过执行Server.CreateObject(“Rsacookieapi.RSACookie”)来获取当前的RSA用户名.GetUserName()。问题是这个特定的com对象不能在MTApartments上运行,只有STAparatments(它们不提供任何替代的.net组件,所以我们必须使用这个),因此CreateObject失败。

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

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

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

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

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

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

我希望这有道理吗?澄清:

  1. 我不希望我的任何控制器或操作在STA上执行
  2. 我想在STA上创建对象,然后从所有其他MTA中访问它
  3. 我衷心希望有人有个建议!

    此致

    卡尔

1 个答案:

答案 0 :(得分:3)

选项1:使用Tlbimp创建程序集。

您是否尝试过使用Tlbimp.exe为组件创建程序集,并使用它?文档说这会导致“性能不佳”。但这是由于所需的编组操作,这与您在此处尝试的操作相同。

http://msdn.microsoft.com/en-us/library/zwk9h2kb.aspx

  

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

选项2:谎言。

如果您只是将注册更改为“both”,那么它可能在您的方案中 。这取决于对象以及如何使用它。

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

(STA意味着只能从一个线程调用该对象。通过在具有不同线程模型的公寓之间进行编组,COM将保证在您共享对象时,您可以假设您公寓中的所有对象都与您的线程模型。但是您也可以通过不共享对象不从任何其他线程调用对象来提供您自己的保证。

要执行此操作,只需进入HKEY_CLASSES_ROOT\CLSID\{guid}下的注册表,然后将ThreadingModel键更改为“Both”。

然后对它进行压力测试。