How to manipulate controls under async Task Main(string[] args)?

1 Answer 7 Views
Form SplashScreen
yw
Top achievements
Rank 2
Iron
Iron
yw asked on 09 Oct 2025, 01:10 PM

I have a WinForm application.

error info:Error message: System.Threading.ThreadStateException: "Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked. This exception is only raised if a debugger is attached to the process." Some of the code is as follows: 1.Partial code of class Program.cs: [STAThread] static async Task Main(string[] args) {

RadSplashScreenManager.ContentCreated += RadSplashScreenManager_ContentCreated;

RadSplashScreenSettings f = new RadSplashScreenSettings()...

var services = new ServiceCollection(); ... services.AddTransient<RadFrmMain>(); await using var sp = services.BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true, ValidateOnBuild = true }); Application.Run(sp.GetRequiredService<RadFrmMain>()); } 2.Partial code inside RadFrmMain.cs: radMenuOpenProject.Name = "radMenuOpenProject"; radMenuOpenProject.Text = "Open Project"; radMenuOpenProject.Click += radMenuOpenProject_Click; private async void radMenuOpenProject_Click(object sender, EventArgs e) { await OpenProjectAsync(); } private async Task OpenProjectAsync() { string? pickedFile = await InvokeOnUiAsync(() => { System.Diagnostics.Debug.Assert( System.Threading.Thread.CurrentThread.GetApartmentState() == System.Threading.ApartmentState.STA, "OpenFileDialog must be called on STA"); var root = string.IsNullOrWhiteSpace(_settings.SqliteRoot) ? "projects_db" : _settings.SqliteRoot; var start = LastPathStore.LoadOr(root); using var ofd = new OpenFileDialog { Title = "Open Project", Filter = "Project files (*.project.json;*.db)|*.project.json;*.db|JSON files (*.project.json)|*.project.json|SQLite (*.db)|*.db|All files (*.*)|*.*", Multiselect = false, InitialDirectory = Directory.Exists(start) ? start : root }; return ofd.ShowDialog(this) == DialogResult.OK ? ofd.FileName : null; //Error message: System.Threading.ThreadStateException: "Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked. This exception is only raised if a debugger is attached to the process." }); } Previously, when using: [STAThread] static void Main() it worked normally, but the project must use static async Task Main(string[] args). How to handle this?


1 Answer, 1 is accepted

Sort by
0
Accepted
Dinko | Tech Support Engineer
Telerik team
answered on 10 Oct 2025, 08:15 AM

Hello yw scr,

The error occurs because WinForms applications require the main thread to run in Single-Threaded Apartment (STA) mode. The [STAThread] attribute ensures this for a synchronous static void Main(). However, when you use static async Task Main(string[] args), the runtime does not guarantee that async continuations will run on an STA thread. This causes issues with OLE-based components like OpenFileDialog, which must be called from an STA thread.

In your post, it was mentioned that you must use static async Task Main(string[] args). Could it be an option to create a separate method? What I have in mind to test is to move the code into an async Task separate method and try to call it from the Main:

[STAThread]
static void Main(string[] args)
{
    // Start your async code synchronously on the STA thread
    RunMainAsync(args).GetAwaiter().GetResult();
}

static async Task RunMainAsync(string[] args)
{
    RadSplashScreenManager.ContentCreated += RadSplashScreenManager_ContentCreated;
    RadSplashScreenSettings f = new RadSplashScreenSettings() { /* ... */ };
    var services = new ServiceCollection();
    // ... configure services
    services.AddTransient<RadFrmMain>();
    await using var sp = services.BuildServiceProvider(new ServiceProviderOptions
    {
        ValidateScopes = true,
        ValidateOnBuild = true
    });
    Application.Run(sp.GetRequiredService<RadFrmMain>());
}
I can't test it as I only have part of the code. I hope that this could work for you.

Regards,
Dinko | Tech Support Engineer
Progress Telerik

Your perspective matters! Join other professionals in the State of Designer-Developer Collaboration 2025: Workflows, Trends and AI survey to share how AI and new workflows are impacting collaboration, and be among the first to see the key findings.
Start the 2025 Survey
yw
Top achievements
Rank 2
Iron
Iron
commented on 10 Oct 2025, 10:31 AM

Thank you for your reply; it's great.

The principle can be found at https://github.com/dotnet/csharplang/blob/main/proposals/csharp-7.1/async-main.md

Tags
Form SplashScreen
Asked by
yw
Top achievements
Rank 2
Iron
Iron
Answers by
Dinko | Tech Support Engineer
Telerik team
Share this question
or