Wpf: If the Main method returns Task, the WPF application will always crash even STAThread is set.

Created on 18 Jun 2019  路  8Comments  路  Source: dotnet/wpf

  • .NET Core Version: 3.0 Preview5
  • Windows version: 10.0.18362.175 (1903)
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes

Problem description:

If I write an async Main method for my WPF application as the code below, the WPF app crashes for the STAThread issue.

static async Task<int> Main(string[] args)
{
    App app = new App();
    app.Run();
}

Actual behavior:

WPF application will crash because the thread is not an STA thread.

Notice that the first frame of the stack trace is a generated <Main> but not the written Main.

Expected behavior:

The WPF app behaves normally without the crash.

Minimal repro:

Add a simple async Main method for any WPF application and this will reproduce.

Most helpful comment

@poizan42 WPF is not the whole application but is part of my application. If some condition occurs, the WPF application will launch, otherwise, the normal command based application launch and return. So the async Main is necessary for such kind of application.

All 8 comments

Not only WPF will crash, but also the other application such as WinForms will crash

May be you can solve it by creating a new STA thread to run the application

That seems like documented behavior? If you are on a MTA thread and wants to spin up some sort of gui then you need to invoke into a STA thread or spawn a new one.

Why would you want to create your WPF app from an async main anyways?

Closing as this is by design.

@poizan42 WPF is not the whole application but is part of my application. If some condition occurs, the WPF application will launch, otherwise, the normal command based application launch and return. So the async Main is necessary for such kind of application.

@grubioe This design ignores a user-defined attribute [STAThread] without any warning or error. Maybe it should be corrected in one of these two methods below:

  1. Make a compiling warning or a compiling error;
  2. Let the [STAThread] work again for async Main entrypoint.

async main + [STAThread] does not make sense, there is no message loop running when you await something in the async main nor do you have a SynchronizationContext for your await to capture, so you could end up resuming on the thread pool (and not on the STA thread!) if you are awaiting early in your async main, and then if you try to create COM objects after awaiting you suddenly create them in MTA, and if the COM objects try to access UI everything goes downhill.

Thats just one example, even if we assume a SynchronizationContext was setup correctly, awaiting would just deadlock because the current implementation of async main (blocking without a message loop from the UI framework) only works on MTA. So generally, unlocking this feature with the current implementation is a very brittle construct with lots of chances for things to go wrong without any warnings to the programmer and probably the main reason why it never was implemented.

If you wanted async main + [STAThread] to work properly the implementation would need to know which UI framework you use so it can set up a message loop correctly. This is rather complicated because async main happens on a different level than UI frameworks, its much easier to let you set it up yourself and drive your own message loop in the way you want to do it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

h82258652 picture h82258652  路  3Comments

poke picture poke  路  3Comments

bugproof picture bugproof  路  3Comments

imanushin picture imanushin  路  3Comments

Pzixel picture Pzixel  路  3Comments