Why doesn’t the .NET Generic Host stop when used with WinUI3?

  .net-5, async-await, c++, windows, winui-3

I’m writing a WinUI3 (Project Reunion 0.5) application with .NET 5 and would like to use the .NET Generic Host. I’m using the default host with a custom IHostedService:

public App() {
    _host = Host.CreateDefaultBuilder()
        .ConfigureServices((context, services) =>
        {
            services.AddHostedService<MyHostedService>();
        }).Build();
    InitializeComponent();
}

The hosted service performs some asynchronous operations in StopAsync. For demonstration purposes, let’s say it delays for 1 second (this code still produces the issue):

public override async Task StopAsync(CancellationToken cancellationToken)
{
    await Task.Delay(1000);
}

I start the host in OnLaunched:

protected override async void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
    await _host.StartAsync();
    m_window = new MainWindow();
    m_window.Activate();
}

I let the default ConsoleLifetime implementation stop the host before the process exits.

The Task returned by my IHostedService.StopAsync implementation completes, but IHost.StopAsync never returns and the process hangs with this message in the output:

Microsoft.Hosting.Lifetime: Information: Application is shutting down...
Microsoft.Hosting.Lifetime: Information: Waiting for the host to be disposed. Ensure all 'IHost' instances are wrapped in 'using' blocks.

If I step through with the debugger, sometimes the IHost.StopAsync method will time out and an exception will be thrown. This never happens outside of the debugger. I have tried explicitly stopping and disposing the host when the MainWindow is closed, but it didn’t make any difference.

I thought perhaps the DispatcherQueueSynchronizationContext was being shut down before the host could stop and tasks were not being serviced, but the DispatcherQueue.ShutdownStarting event is never fired.

Any other ideas?

Source: Windows Questions

LEAVE A COMMENT