Uncaught OperationCancelledException when shutting down IHostedService

Is there a way to detect that OperationCancelledException was thrown specifically due to application shutdown (e.g. pressing "stop" button in IDE)?
19 Replies
FusedQyou
FusedQyou4w ago
I assume the Run(Async) method throws this, so you can try-catch there
Unknown User
Unknown User4w ago
Message Not Public
Sign In & Join Server To View
FusedQyou
FusedQyou4w ago
I assume the issue is the fact that the process cancels due to shutdown, and the question is how you would gracefully shut down when that happens
Unknown User
Unknown User4w ago
Message Not Public
Sign In & Join Server To View
FusedQyou
FusedQyou4w ago
So how would you check IsCancellationRequested if the code throws Then it's too late
Unknown User
Unknown User4w ago
Message Not Public
Sign In & Join Server To View
FusedQyou
FusedQyou4w ago
Yes so the code throws
Unknown User
Unknown User4w ago
Message Not Public
Sign In & Join Server To View
FusedQyou
FusedQyou4w ago
So it should gracefully shutdown with a try-catch
Unknown User
Unknown User4w ago
Message Not Public
Sign In & Join Server To View
FusedQyou
FusedQyou4w ago
No point in checking IsCancellationRequested when the exception already thrown
Unknown User
Unknown User4w ago
Message Not Public
Sign In & Join Server To View
SilverShade
SilverShadeOP4w ago
public abstract class BackgroundService : IHostedService
{
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();

protected abstract Task ExecuteAsync(CancellationToken stoppingToken);

public virtual Task StartAsync(CancellationToken cancellationToken)
{
_executingTask = ExecuteAsync(_stoppingCts.Token);
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}

public virtual async Task StopAsync(CancellationToken cancellationToken)
{
if (_executingTask == null)
return;

try
{
_stoppingCts.Cancel();
}
finally
{
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
}
public abstract class BackgroundService : IHostedService
{
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();

protected abstract Task ExecuteAsync(CancellationToken stoppingToken);

public virtual Task StartAsync(CancellationToken cancellationToken)
{
_executingTask = ExecuteAsync(_stoppingCts.Token);
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}

public virtual async Task StopAsync(CancellationToken cancellationToken)
{
if (_executingTask == null)
return;

try
{
_stoppingCts.Cancel();
}
finally
{
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
}
Cant share the original code since it’s proprietary, but the logic is roughly the same as here, taken from an open source article
Unknown User
Unknown User4w ago
Message Not Public
Sign In & Join Server To View
SilverShade
SilverShadeOP4w ago
Yeah it’s not in my app
Unknown User
Unknown User4w ago
Message Not Public
Sign In & Join Server To View
SilverShade
SilverShadeOP4w ago
Ig if i were to write pseudo code for it, the snippet i just sent would be it So yeah it best describes what is implemented in my code
Unknown User
Unknown User4w ago
Message Not Public
Sign In & Join Server To View
SilverShade
SilverShadeOP4w ago
Hmm yeah i’ll try to implement that, thanks!♥️
Want results from more Discord servers?
Add your server