【问题标题】:How many 'STA' threads can coexist inside a process?一个进程内可以共存多少个“STA”线程?
【发布时间】:2014-09-09 02:16:42
【问题描述】:

我的 ASP.NET 应用程序中需要多个 STA 线程来使用一些 COM 组件。

我在每个进程的某个地方读到,只能存在一个STA 线程。我编写了一个示例项目并创建了许多线程并将它们的单元状态设置为STA,它们毫无例外地使用COM 对象。

一个进程中是否可以有多个STA 线程?

【问题讨论】:

标签: c# multithreading sta apartment-state


【解决方案1】:

您可以拥有的 STA 线程数没有固有限制,但是您可能希望自己施加这样的限制。

如果您允许您的 ASP.NET 应用程序在新用户请求到达时创建额外的 STA 线程,但不限制它,最终线程数将导致您的应用程序的性能下降,因为 CPU 花费在上下文切换上的时间量变得太高了。这也使您的应用程序更容易受到拒绝服务攻击。

您可以考虑这样一种设计:根据您的硬件或用户配置文件设置 STA 线程的数量限制,一旦达到限制,实施一些池化以重用现有 STA 线程来服务新请求。

【讨论】:

  • +1 用于限制线程创建。正是那种会在生产中咬你的东西。
  • 我在考虑使用线程池,但可能从线程池设置线程的单元类型会产生一些问题,因为线程的单元类型不能多次切换。
  • 如果我没记错的话,ThreadPool 线程总是 MTA。无论如何,将 ThreadPool 用于 STA COM 对象可能是一个非常糟糕的主意。 STA 线程需要泵送消息,而 ThreadPools 线程在完成您排队的工作项后不会泵送。在 ThreadPool 上创建 STA COM 对象甚至可能导致终结器线程被阻塞,从而导致内存泄漏。
【解决方案2】:

如果您的程序与许多 STA 线程一起工作,那么您为什么要问它是否工作? :) .NET 允许您拥有任意数量的 STA 线程,因此它必须工作。不过,对于只有一个主线程和一个消息循环的典型本机应用程序,您所读到的内容可能是正确的。

【讨论】:

    【解决方案3】:

    没有上限,除了内存。当线程堆栈耗尽所有可用地址空间时,一个 32 位进程通常会减少 2000 个线程。

    牢记规则,您不能在没有编组的情况下从另一个 STA 调用在一个 STA 中创建的对象。并且不要忘记所需的消息循环,STA 线程必须泵送以保持编组活动并防止死锁。显然,应强烈避免接近内存限制。

    【讨论】:

      【解决方案4】:

      标准 STA 线程没有真正的限制,但对于具有消息循环的 UI,只有一个“特殊”STA 线程。这可能是你在别处读到的。虽然大多数 COM 都适用于任何 STA 线程,但某些 COM 可能需要消息循环(例如用于计时器计时),这将需要指向 UI 线程或消息泵送。

      Is STA Message Loop Required in This Case?

      http://blogs.msdn.com/b/cbrumme/archive/2004/02/02/66219.aspx

      【讨论】:

        猜你喜欢
        • 2012-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多