C# 多线程/并行启动和停止辅助角色服务中的托管服务

C# Multithreaded/ Parallel start and stop of hosted services in worker service

提问人:mathisplewa 提问时间:10/4/2023 最后编辑:mathisplewa 更新时间:10/4/2023 访问量:46

问:

在我的应用程序中,我使用的是 dotnet 辅助角色服务模板 (.NET6)。在我的 I add multiple via 方法中。我添加的服务数量可能在几十个之间变化。我添加的每个辅助角色 (IHostedService) 都继承自该类。 然后,在我的工作线程中,我覆盖了该方法。如下所示:program.csIHostedServiceAddSingletonBackgroundServiceStopAsync

        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 服务的最大关闭时间。

我有一种感觉,无论是在设置服务的方式上,还是在异步和等待方面,我都做错了什么。

C# 多线程 ASP.NET-Core 异步 await

评论

1赞 Fildor 10/4/2023
该怎么办?看起来相关代码会在那里?到目前为止,该片段对我来说看起来还不错。ExitProcessor()
0赞 mathisplewa 10/4/2023
@Fildor 为您编辑了我的问题。基本上,在退出过程中,它会非常深入,但是它们都是异步等待的。
1赞 BurnsBA 10/4/2023
async并不意味着并行,而是意味着它不会挂在 IO 绑定任务上
4赞 Panagiotis Kanavos 10/4/2023
expecting the StopAsync to hit all the workers at the same time.期望是错误的。 仅当应用程序终止且不在单独的线程中运行时调用。允许代码调用异步操作是异步的。 并且也不要在单独的线程中运行。如果这些方法从未产生,它们将同步完成。托管服务中没有同步上下文(没有 UI 或 ASP.NET Core 请求),因此没有任何影响StopAsyncStartAsyncExecuteAsyncConfigureAwait(false)
2赞 Stephen Cleary 10/4/2023
Panagiotis是正确的。不过,在 .net 8 中有一个并发关闭选项

答: 暂无答案