AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
24.76k stars 2.15k forks source link

StorageProvider.OpenFolderPickerAsync() can not work if ```Main``` entrance is ```Async``` #15806

Open perfect100 opened 2 months ago

perfect100 commented 2 months ago

Describe the bug

If the Main entrance point is a void method, it works.

    public static void Main(string[] args)
    {
        var appBuilder = BuildAvaloniaApp();
        appBuilder.StartWithClassicDesktopLifetime(args);
    }

However, if the function is async , the folder picker will never return, and UI blocks.

    public static async Task Main(string[] args)
    {
        var appBuilder = BuildAvaloniaApp();
        appBuilder.StartWithClassicDesktopLifetime(args);
        await // todo...
    }

In this scenario, the code will be blocked here: https://github.com/AvaloniaUI/Avalonia/blob/eb7b6fe8435dfc3eae45907010b293f1ebc8d129/src/Windows/Avalonia.Win32/Win32StorageProvider.cs#L155

To Reproduce

Only can reproduce in some special machine... Most of the machines work well

Expected behavior

It should always work, no matter of the Main method is async or not.

Avalonia version

11.1.0-beta1

OS

Windows

Additional context

If I debug into this function in Avalonia.Win32.Win32StorageProvider.ShowFilePicker() step by step, the folder picker shows normally.

image

maxkatz6 commented 2 months ago

It's something good to mention in the documentation, but I don't think it's possible to support. IFileDialog requires main thread to be a STA thread.

See https://github.com/dotnet/roslyn/issues/22112

Also, "async Main" break macOS apps fundamentally too, but for different reasons. Only first physical thread can be main thread there.

perfect100 commented 2 months ago

Woo, that's really teach me a great lesson. I have spent 3 days to investigate the issue. Many thanks @maxkatz6