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://learn.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);
}
I know this is old, but Damien's answer and the subsequent comment helped me with my issue. I have a console app in which I need to call async
methods that at some point may need STA execution to use the OpenFileDialog
.
Here is my resulting code in case it helps others (or just my future self).
1. Created Extension Method for running thread as STA
public static class Extensions
{
public static void RunSTA(this Thread thread)
{
thread.SetApartmentState(ApartmentState.STA); // Configure for STA
thread.Start(); // Start running STA thread for action
thread.Join(); // Sync back to running thread
}
}
2. Created async main
method with await
to application method (no [STAThread]
attribute).
class Program
{
static async Task Main(string[] args)
{
await App.Get().Run(args);
}
}
3. Use extension method to wrap OpenFileDialog
call with STA
public string[] GetFilesFromDialog(string filter, bool? restoreDirectory = true, bool? allowMultiSelect = true)
{
var results = new string[] { };
new Thread(() =>
{
using (var dialog = new OpenFileDialog())
{
dialog.Filter = filter;
dialog.RestoreDirectory = restoreDirectory ?? true;
dialog.Multiselect = allowMultiSelect ?? true;
if (dialog.ShowDialog() != DialogResult.OK)
return; // Nothing selected
results = dialog.FileNames;
}
}).RunSTA();
return results;
}