C
C#2mo ago
SilverShade

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
FusedQyou2mo ago
I assume the Run(Async) method throws this, so you can try-catch there
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
FusedQyou
FusedQyou2mo 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 User2mo ago
Message Not Public
Sign In & Join Server To View
FusedQyou
FusedQyou2mo ago
So how would you check IsCancellationRequested if the code throws Then it's too late
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
FusedQyou
FusedQyou2mo ago
Yes so the code throws
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
FusedQyou
FusedQyou2mo ago
So it should gracefully shutdown with a try-catch
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
FusedQyou
FusedQyou2mo ago
No point in checking IsCancellationRequested when the exception already thrown
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
SilverShade
SilverShadeOP2mo 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 User2mo ago
Message Not Public
Sign In & Join Server To View
SilverShade
SilverShadeOP2mo ago
Yeah it’s not in my app
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
SilverShade
SilverShadeOP2mo 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 User2mo ago
Message Not Public
Sign In & Join Server To View
SilverShade
SilverShadeOP2mo ago
Hmm yeah i’ll try to implement that, thanks!♥️

Did you find this page helpful?