A Worker Service is the new way to write a Windows service in .NET Core 3.x. The worker class extends [`Microsoft.Extensions.Hosting.BackgroundService`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.backgroundservice?view=dotnet-plat-ext-3.1) and implements `ExecuteAsync`. The documentation for that method says:

> 
> This method is called when the IHostedService starts. The implementation should return a task that represents the lifetime of the long running operation(s) being performed.
> 
> 
> 

What should this method return when the work being done by the service is not a long-running operation in the usual sense, but event-driven? For example, I'm writing a service that sets up a [`FileSystemWatcher`](https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=netcore-3.1). How would I encapsulate that in a `Task`? There's no `Task.Never()`, so should I just return something based on a very long `Task.Delay()` to prevent the service from shutting down?

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

```
['https://Stackoverflow.com/questions/63196690', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/8773089/']
You could also use an actual infinite delay:

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

```
If you want to call it like `await "Eternity"` or `await ("Eternity", token)` if you want cancellation support. We can use them with cancellation support thanks to value tuples.

Basically *you can await anything* with some extension methods.

Here is the code:

```
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();
        }
    }

```