dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.31k stars 4.74k forks source link

Async method throwing before await throws unobserved exception on Android only #109464

Open dotMorten opened 2 years ago

dotMorten commented 2 years ago

Android application type

Android for .NET (net6.0-android, etc.)

Affected platform version

VS2022, Version 17.3.0 Preview 2.0

Description

If I have a Task method that throws before the async work is done, without awaiting that method will cause the method to immediately throw on Windows and iOS. However on Android this call doesn't throw. and instead throws an unobserved task exception later.

Steps to Reproduce

  1. Create a new .NET MAUI application
  2. Replace the MainPage.xaml.cs code with the following:

    public MainPage()
    {
        InitializeComponent();
        TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
    }
    
    private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
    {
        Dispatcher.Dispatch(() =>
        {
            CounterBtn.Text = $"UnobservedTaskException thrown";
        });
        e.SetObserved();
    }
    
    private void OnCounterClicked(object sender, EventArgs e)
    {
        try
        {
            _ = OperationAsync(null);
            CounterBtn.Text = $"No exception thrown !";
        }
        catch (ArgumentNullException)
        {
            CounterBtn.Text = $"Exception thrown as expected";
        }
    }
    private async Task OperationAsync(object arg)
    {
        if (arg is null) throw new ArgumentNullException(nameof(arg));
        await Task.Delay(1000);
    }

    Run the application on Windows and iOS, and note button text changes to Exception thrown as expected. Next run this on Android, and note that first the button text changes to No exception thrown !, shortly after followed by UnobservedTaskException Thrown.

Did you find any workaround?

Await your tasks

Relevant log output

No response

grendello commented 2 years ago

Soo... this is interesting. It appears that Neither of the above behaviors is correct. I ported your sample to plain Xamarin.Android and I get yet another result - the exception isn't thrown at all.

We appear to have 4 different behaviors:

  1. MAUI iOS/Windows: the exception is thrown immediately
  2. MAUI Android: the exception is thrown with a delay, caught by the unhandled exception handler
  3. Plain Xamarin.Android/.NET6 CoreCLR Windows/dotnet MonoVM Windows/.NET7 Desktop MonoVM/.NET7 CoreCLR Windows/WinUI: the exception is never thrown

It appears that 3. is the correct behavior.

PureWeen commented 2 years ago

@grendello I've attached a WinUI app without MAUI and one that is MAUI. Both scenarios behave the same.

WinUI ExceptionTest.zip

MAUI MauiApp38.zip

dotnet-policy-service[bot] commented 1 week ago

Tagging subscribers to this area: @mangod9 See info in area-owners.md if you want to be subscribed.

dotnet-policy-service[bot] commented 1 week ago

Tagging subscribers to 'arch-android': @vitek-karas, @simonrozsival, @steveisok, @akoeplinger See info in area-owners.md if you want to be subscribed.