mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
50 lines
1.6 KiB
C#
50 lines
1.6 KiB
C#
|
using Microsoft.Extensions.Hosting;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Text;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace Teknik.Utilities
|
|||
|
{
|
|||
|
public abstract class HostedService : IHostedService
|
|||
|
{
|
|||
|
private Task _executingTask;
|
|||
|
private CancellationTokenSource _cts;
|
|||
|
|
|||
|
public Task StartAsync(CancellationToken cancellationToken)
|
|||
|
{
|
|||
|
// Create a linked token so we can trigger cancellation outside of this token's cancellation
|
|||
|
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
|||
|
|
|||
|
// Store the task we're executing
|
|||
|
_executingTask = ExecuteAsync(_cts.Token);
|
|||
|
|
|||
|
// If the task is completed then return it, otherwise it's running
|
|||
|
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
|
|||
|
}
|
|||
|
|
|||
|
public async Task StopAsync(CancellationToken cancellationToken)
|
|||
|
{
|
|||
|
// Stop called without start
|
|||
|
if (_executingTask == null)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Signal cancellation to the executing method
|
|||
|
_cts.Cancel();
|
|||
|
|
|||
|
// Wait until the task completes or the stop token triggers
|
|||
|
await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));
|
|||
|
|
|||
|
// Throw if cancellation triggered
|
|||
|
cancellationToken.ThrowIfCancellationRequested();
|
|||
|
}
|
|||
|
|
|||
|
// Derived classes should override this and execute a long running method until
|
|||
|
// cancellation is requested
|
|||
|
protected abstract Task ExecuteAsync(CancellationToken cancellationToken);
|
|||
|
}
|
|||
|
}
|