ElementHost does not work in MTAThread

399 views Asked by At

I have WPF User Control which needs to hosted inside Windows Form in MTAThread. And solution should work with both STAThread and MTAThread. And technically there is no option to change the Apartment State in production environment.

Program.cs

[MTAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}  

void Form1_Load(object sender, EventArgs e)
{
    Thread t = new Thread(() =>{
    host = new ElementHost();
    host.Dock = DockStyle.Fill;
    uc = new UserControl1();
    host.Child = uc;
    });
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
            t.Join();
            MessageBox.Show(this.Controls.Count.ToString());
            //if (this.InvokeRequired)
            //{
            //    this.Invoke((Action)(() => { this.Controls.Add(host); }));
            //}
            //else
            {
                this.Controls.Add(host);
            }
            MessageBox.Show(this.Controls.Count.ToString());
}

In this case, Now host is added to the control as there is increase in the count and it does not throw any exception in MTAThread. But WPF User Control is not rendering. However, in STAThread it is throwing an exception "Calling Thread can not access this object...."

Anyhelp in this would be greatly appreciated.

1

There are 1 answers

1
Joachim Rosskopf On

I'm not completely sure, but most likely the ElementHost Windows-Forms control is a wrapper around a COM/ActiveX-Object.

And as COM/ActiveX UI controls are not thread safe on their own, they have to run in STA appartment. An very well posed explanation can be found here.

So I think, you have no real choice and have to change your entry-thread to STA.