.net core 当工作进程是事件驱动的时,BackgroundService.ExecuteAsync应该返回什么?

.net core 当工作进程是事件驱动的时,BackgroundService.ExecuteAsync应该返回什么?,.net-core,windows-services,.net-core-3.1,.net Core,Windows Services,.net Core 3.1,辅助服务是在.NETCore3.x中编写Windows服务的新方法。worker类扩展并实现了ExecuteAsync。该方法的文档说明: IHostedService启动时调用此方法。实现应该返回一个任务,该任务表示正在执行的长时间运行操作的生存期 当服务所做的工作不是通常意义上的长时间运行的操作,而是事件驱动的操作时,该方法应该返回什么?例如,我正在编写一个服务,它设置了一个。我如何将其封装在任务中?没有Task.Never(),因此我是否应该基于很长的Task.Delay()返回一些内容以

辅助服务是在.NETCore3.x中编写Windows服务的新方法。worker类扩展并实现了
ExecuteAsync
。该方法的文档说明:

IHostedService启动时调用此方法。实现应该返回一个任务,该任务表示正在执行的长时间运行操作的生存期

当服务所做的工作不是通常意义上的长时间运行的操作,而是事件驱动的操作时,该方法应该返回什么?例如,我正在编写一个服务,它设置了一个。我如何将其封装在
任务中
?没有
Task.Never()
,因此我是否应该基于很长的
Task.Delay()
返回一些内容以防止服务关闭

private async Task DoStuffAsync(CancellationToken cancel)
{
  // register events
  while(!cancel.IsCancellationRequested)
  {
    await Task.Delay(TimeSpan.FromDays(1000000), cancel);
  }
  // unregister events
}

我将延迟合并到一个名为
永恒
的方法中:

private async Task Eternity(CancellationToken cancel)
{
    while (!cancel.IsCancellationRequested)
    {
        await Task.Delay(TimeSpan.FromDays(1), cancel);
    }
}
因此,我的
ExecuteAsync
看起来像:

protected override async Task ExecuteAsync(CancellationToken cancel)
{
    using (var watcher = new FileSystemWatcher())
    {
        ConfigureWatcher(watcher);
        await Eternity(cancel);
    }
}

这似乎与预期一样有效。

您也可以使用实际的无限延迟:

await Task.Delay(Timeout.Infinite, cancellationToken);

如果您想像
等待“永恒”
等待(“永恒”,令牌)
那样调用它,如果您想要取消支持。由于值元组,我们可以将它们与取消支持一起使用

基本上,您可以通过一些扩展方法等待任何东西

代码如下:

protected override async Task ExecuteAsync(CancellationToken token)
        {
            using (var watcher = new FileSystemWatcher())
            {
                ConfigureWatcher(watcher);
                
                // Use any of these methods you'd like
                await "Eternity";
                await ("Eternity", token);
                await TimeSpan.FromDays(1);
                await (TimeSpan.FromDays(1), token);
            }
        }

public static class GetAwaiterExtensions 
    {
        public static TaskAwaiter GetAwaiter(this (TimeSpan, CancellationToken) valueTuple)
        {
            return Task.Delay((int) valueTuple.Item1.TotalMilliseconds, valueTuple.Item2)
                .GetAwaiter();
        }
        
        public static TaskAwaiter GetAwaiter(this TimeSpan timeSpan)
        {
            return Task.Delay((int) timeSpan.TotalMilliseconds)
                .GetAwaiter();
        }
        
        public static TaskAwaiter GetAwaiter(this string value)
        {
            if (value == "Eternity")
            {
                return Task.Delay(Timeout.Infinite)
                    .GetAwaiter();
            }
            
            throw new ArgumentException();
        }
        
        public static TaskAwaiter GetAwaiter(this (string, CancellationToken) valueTuple)
        {
            if (valueTuple.Item1 == "Eternity")
            {
                return Task
                    .Delay(Timeout.Infinite, cancellationToken: valueTuple.Item2)
                    .GetAwaiter();
            }
            
            throw new ArgumentException();
        }
    }

不像等待永恒那样有趣,但很高兴知道这是正确的方法。