Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set ApartmentState for async void main

I have a Windows Forms app.

Now I want to use an async method.

Since C# 7.1 I can use an async Main method:
https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7-1

However, now my STAThread attribute is ignored and my app runs in MTA. Is this by design or can I force my app to run in STA mode again?

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static async Task Main(string[] args)
{
    // returns MTA
    Console.WriteLine("{0}", Thread.CurrentThread.ApartmentState);
}
like image 371
Jürgen Steinblock Avatar asked Nov 29 '17 12:11

Jürgen Steinblock


Video Answer


1 Answers

An STA is one in which you promise that a single thread will operate a windows message pump (usually hidden behind a call to Application.Run()). You'll run the message pump on your thread when it's not otherwise occupied.

An async method is one which, when it's got nothing better to do, will release its thread to go off and do other things.

I can't get those two concepts to align. If you want STA, you want to keep hold of that thread and pump messages. So using async main doesn't make sense there.


In this particular circumstance (various initialization steps that could benefit from await followed by an Application.Run I would use the async Main without the STAThread attribute. I would then explicitly create an STA thread specifically for then running the windows message loop.

There's no rule that the first thread in your program has to be the/a STA thread and I think this provides the cleanest separation. If your async Main has no further useful work to do you may want to share a TaskCompletionSource between Main and the message-loop-running thread that then signals completion once Application.Run() returns.

like image 145
Damien_The_Unbeliever Avatar answered Sep 22 '22 21:09

Damien_The_Unbeliever