提问人:mathisplewa 提问时间:10/4/2023 最后编辑:mathisplewa 更新时间:10/4/2023 访问量:46
C# 多线程/并行启动和停止辅助角色服务中的托管服务
C# Multithreaded/ Parallel start and stop of hosted services in worker service
问:
在我的应用程序中,我使用的是 dotnet 辅助角色服务模板 (.NET6)。在我的 I add multiple via 方法中。我添加的服务数量可能在几十个之间变化。我添加的每个辅助角色 (IHostedService) 都继承自该类。
然后,在我的工作线程中,我覆盖了该方法。如下所示:program.cs
IHostedService
AddSingleton
BackgroundService
StopAsync
public override async Task StopAsync(CancellationToken cancellationToken)
{
using (LogContext.PushProperty("Name", Name))
{
try
{
//--------------------------------------------------------------------
// From here on we exit
//--------------------------------------------------------------------
Stopwatch exitWatch = Stopwatch.StartNew();
Logger?.Log(LogLevel.Information, "Start exit procedures");
await ExitProcessor().ConfigureAwait(false);
Logger?.Log(LogLevel.Information, "Execute procedures finished in <{elapsedMilliseconds}> ms", exitWatch.ElapsedMilliseconds);
exitWatch.Stop();
//--------------------------------------------------------------------
// And signal to the host
//--------------------------------------------------------------------
await base.StopAsync(cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
Logger?.Log(LogLevel.Error, "{ex}", ex);
}
}
}
ExitProcessor 方法基本上如下所示:
private async Task ExitProcessor()
{
await ExitSource().ConfigureAwait(false);
await Exit().ConfigureAwait(false);
await ExitSink().ConfigureAwait(false);
}
在正常关闭我的应用程序时,我期望 StopAsync 同时命中所有工作线程。然而,情况似乎并非如此。整个 worker 服务的停止似乎是同步的。
随着关闭时间的增加,我添加的 IHostedServices 越多,这就会成为一个问题,有时它可能会达到例如 systemd 服务的最大关闭时间。
我有一种感觉,无论是在设置服务的方式上,还是在异步和等待方面,我都做错了什么。
答: 暂无答案
评论
ExitProcessor()
async
并不意味着并行,而是意味着它不会挂在 IO 绑定任务上expecting the StopAsync to hit all the workers at the same time.
期望是错误的。 仅当应用程序终止且不在单独的线程中运行时调用。允许代码调用异步操作是异步的。 并且也不要在单独的线程中运行。如果这些方法从未产生,它们将同步完成。托管服务中没有同步上下文(没有 UI 或 ASP.NET Core 请求),因此没有任何影响StopAsync
StartAsync
ExecuteAsync
ConfigureAwait(false)