Soetch
Soetch

Reputation: 19

"The calling thread must be STA, because many UI components require this."

I am trying to get a window to open in plain C#. I've created, for this, a window constructor (SGFWindow) extending the Window class from System.Windows :

namespace SGF
{
    public partial class SGFWindow : Window
    {
        public SGFWindow() 
        {
            this.Title = "SGF Window";
            this.Width = 200;
            this.Height = 200;
        }
    }
}

I've then created a WindowTest class to test it :

namespace SGF
{
    public class WindowTest
    {
        public static void Main(string[] args)
        {
            SGFWindow window = new SGFWindow();
            window.Show();
        }
    }
}

The problem is, I get a "The calling thread must be STA, because many UI components require this." error ; excepting that this is not a thread (or not one I've created?).

I searched about it but it was always about a thread and I can't find how to fix this error. I've also saw something about [STAThread] but it apparently wasn't appropriate to it.

Thanks in advance, Marceau.

Upvotes: -2

Views: 3895

Answers (3)

psulek
psulek

Reputation: 4428

Also if you use top level statements class (C# 9.0 and higher) to run your WPF/WinForms app, u need to call:

Thread.CurrentThread.SetApartmentState(ApartmentState.Unknown);
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);

Like mentioned in github/dotnet/winforms issue.

Reason is that top level statements class cannot have any attributes to by applied on like standard Program/main method, there is not way where you can write [STAThread].

Upvotes: 0

Etienne de Martel
Etienne de Martel

Reputation: 36986

There is a thread, actually, because threads are required to execute code. In fact, there will always be at least one: the operating system will create one for you to execute the Main method, and that one is referred to as the "main thread". When Main returns, that thread exits.

By default, that thread is created as MTA, but this is not appropriate for WinForms and WPF, hence why you get that error. The solution is to put the STAThread attribute over your Main to change this:

[STAThread]
public static void Main(string[] args)
{
    SGFWindow window = new SGFWindow();
    window.Show();
}

This attribute is only used to change the threading model of the main thread. For a thread you've created yourself, use Thread.SetApartmentState.

Upvotes: 7

Fabian Flattinger
Fabian Flattinger

Reputation: 27

you can create a new Thread with the Appartment .STA.

Thread thread = new Thread(() => FantasticMethod());
thread.SetApartmentState(ApartmentState.STA);
thread.Start();

in the Thread you can put your method.

I'm not sure right now, but you can also use:

Application.Current.Dispatcher.Invoke(() => FantasticMethod());

The Error means that you are have to be in the UI Thread

Hope this helps you

Upvotes: -1

Related Questions