Single-threaded apartment - cannot instantiate ActiveX control
Asked Answered
B

4

74

I need to get information about applied CSS styles in HTML page. I used AxWebBrowser and iterate IHTMLDOMNode. I'm able to get all the data I need and move the code into my application. The problem is that this part is running inside of the background worker and I got exception when trying to instantiate the control.

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.

Is there any way how to solve this or other option than AxWebBrowser?

Blasius answered 13/9, 2009 at 18:21 Comment(0)
U
97

The problem you're running into is that most background thread / worker APIs will create the thread in a Multithreaded Apartment state. The error message indicates that the control requires the thread be a Single Threaded Apartment.

You can work around this by creating a thread yourself and specifying the STA apartment state on the thread.

var t = new Thread(MyThreadStartMethod);
t.SetApartmentState(ApartmentState.STA);
t.Start();
Universally answered 13/9, 2009 at 18:23 Comment(8)
Thanks, great this is working. One more questions/problem. The class I'm using is just class and the AxWebBrowser looks like it needs to be added into this.Controls(). Is there way how to fake the Controls? Or will I need to have separated Form for that?Blasius
@Blasius There's no great way to fake that. The best bet is to create a new form.Universally
Hi, the code should be t.SetApartmentState(ApartmentState.STA);Tint
Confirmed Dawkins comment, I also had to change it to AppartmentState.STA.Finesse
I've met this error when I want to open a windowsfrom from my XNA-Game. I've opened the form with JaredPar's code and it works. Can I carry this code inside the windows form's code ?Chorus
Beware that this code is not enough to properly implement an STA thread, it must also pump a message loop. Particularly WebBrowser will malfunction, it will not fire its DocumentCompleted event. Check this post for an alternative.Joule
How do you do this in the Compact Framework. (i.e. compact framework has no [STAThread] ability.)Merrileemerrili
I am using Task, is there any solution?Cardio
A
68

Go ahead and add [STAThread] to the main entry of your application, this indicates the COM threading model is single-threaded apartment (STA)

example:

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());
    }
}
Anyone answered 21/5, 2011 at 17:37 Comment(1)
doesnt work in framework 4.5 - gives invalid arguments on last lineGoldplate
S
4

If you used [STAThread] to the main entry of your application and still get the error you may need to make a Thread-Safe call to the control... something like below. In my case with the same problem the following solution worked!

Private void YourFunc(..)
{
    if (this.InvokeRequired)
    {
        Invoke(new MethodInvoker(delegate()
        {
           // Call your method YourFunc(..);
        }));
    }
    else
    {
        ///
    }
Sty answered 12/12, 2014 at 18:16 Comment(1)
What should be invoked in here? The browser? In which state? In my case the browser is sitting on a dialog.Graveclothes
I
1

My problem with this was that I had my Main method marked as async. So fixed it just by making it static void and adding .wait() to all awaitable methods inside.

Ignatzia answered 13/10, 2021 at 11:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.