gpt4 book ai didi

c# - 与 WinUI3 一起使用时,为什么 .NET 通用主机不停止?

转载 作者:行者123 更新时间:2023-12-04 07:33:43 25 4
gpt4 key购买 nike

我正在使用 .NET 5 编写 WinUI3(Project Reunion 0.5)应用程序,并希望使用 .NET 通用主机。我正在使用带有自定义的默认主机 IHostedService :

public App() {
_host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
services.AddHostedService<MyHostedService>();
}).Build();
InitializeComponent();
}
托管服务在 StopAsync 中执行一些异步操作.出于演示目的,假设它延迟了 1 秒(此代码仍然会产生问题):
public override async Task StopAsync(CancellationToken cancellationToken)
{
await Task.Delay(1000);
}
我在 OnLaunched启动主机:
protected override async void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
await _host.StartAsync();
m_window = new MainWindow();
m_window.Activate();
}
我让默认 ConsoleLifetime实现在进程退出之前停止主机。 Task由我的 IHostedService.StopAsync 退回实现完成,但 IHost.StopAsync永远不会返回并且进程在输出中挂起此消息:
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.
如果我使用调试器逐步调试,有时会出现 IHost.StopAsync方法将超时并抛出异常。这永远不会发生在调试器之外。我尝试在 MainWindow 时显式停止和处理主机。已关闭,但没有任何区别。
我想也许是 DispatcherQueueSynchronizationContext在主机可以停止并且任务没有得到服务之前被关闭,但是 DispatcherQueue.ShutdownStarting事件永远不会被触发。
还有其他想法吗?

最佳答案

我从评论中接受了@Dai 的建议,并调查了在单独的线程上运行 WinUI 并在主线程上运行主机的情况。
我创建了一个 IHostedService管理 WinUI 应用程序:

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Microsoft.System;
using Microsoft.UI.Xaml;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace MyApp.Hosting
{

public class WinUIHostedService<TApplication> : IHostedService, IDisposable
where TApplication : Application, new()
{
private readonly IHostApplicationLifetime HostApplicationLifetime;
private readonly IServiceProvider ServiceProvider;

public WinUIHostedService(
IHostApplicationLifetime hostApplicationLifetime,
IServiceProvider serviceProvider)
{
HostApplicationLifetime = hostApplicationLifetime;
ServiceProvider = serviceProvider;
}

public void Dispose()
{
}

public Task StartAsync(CancellationToken cancellationToken)
{
var thread = new Thread(Main);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}

private void Main()
{
WinRT.ComWrappersSupport.InitializeComWrappers();
Application.Start((p) => {
var context = new DispatcherQueueSynchronizationContext(DispatcherQueue.GetForCurrentThread());
SynchronizationContext.SetSynchronizationContext(context);
new TApplication();
});
HostApplicationLifetime.StopApplication();
}
}

}
我定义了 DISABLE_XAML_GENERATED_MAIN在build设置中添加了我自己的 Main :
public class Program
{
public static void Main(string[] args)
{
Host.CreateDefaultBuilder()
.ConfigureServices(services =>
{
services.AddHostedService<WinUIHostedService<App>>();
})
.Build().Run();
}
}
瞧!即使在 IHostedService.StopAsync 关闭主窗口时,WinUI 应用程序仍然可以正常运行并且主机会完全停止。运行异步代码。
请注意,此代码只是第一个起作用的东西。它可能会得到改进,我不完全理解通用主机生命周期语义。

关于c# - 与 WinUI3 一起使用时,为什么 .NET 通用主机不停止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67825363/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com