代码之家  ›  专栏  ›  技术社区  ›  martin.malek

单线程单元-无法实例化ActiveX控件

  •  58
  • martin.malek  · 技术社区  · 15 年前

    我需要获取有关HTML页面中应用的CSS样式的信息。我使用AxWebBrowser并迭代IHTMldomnode。我能够获取我需要的所有数据,并将代码移动到我的应用程序中。问题是这部分运行在后台工作程序内部,我在尝试实例化控件时遇到异常。

    AxWebBrowser browser = new AxWebBrowser();
    
    ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated
    because the current thread is not in a single-threaded apartment.
    

    除了AxWebBrowser,还有其他方法可以解决这个问题吗?

    3 回复  |  直到 10 年前
        1
  •  74
  •   Factor Mystic    14 年前

    您遇到的问题是,大多数后台线程/工作API将在多线程单元状态下创建线程。错误消息指示控件要求线程是单线程单元。

    您可以通过自己创建一个线程并在线程上指定sta单元状态来解决这个问题。

    var t = new Thread(MyThreadStartMethod);
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
    
        2
  •  59
  •   user764177    14 年前

    继续将[stathread]添加到应用程序的主条目中,这表明COM线程模型是单线程单元(sta)。

    例子:

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new WebBrowser());
        }
    }
    
        3
  •  4
  •   Ahmad    10 年前

    如果你用过 [STAThread] 到应用程序的主条目,仍然会得到可能需要的错误 线程安全调用 到控件…像下面这样。在我的例子中,同样的问题,下面的解决方案是有效的!

    Private void YourFunc(..)
    {
        if (this.InvokeRequired)
        {
            Invoke(new MethodInvoker(delegate()
            {
               // Call your method YourFunc(..);
            }));
        }
        else
        {
            ///
        }