Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is preferred in the while loop of the RunAsync method in a Service: use IsCancellationRequested or throw exception

Tags:

Why is the sample RunAsync for new Service Fabric code structured like this

protected override async Task RunAsync(CancellationToken cancellationToken)
{
  while(true)
  {
    cancellationToken.ThrowIfCancellationRequested();

    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
  }
} 

instead of this

protected override async Task RunAsync(CancellationToken cancellationToken)
{
  while(cancellationToken.IsCancellationRequested)
  {
    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
  }
} 

Wouldn't the version without the throw be preferred? The docs state that both implementations are correct: "The system will wait for your task to end (by successful completion, cancellation, or fault)".

like image 283
Michiel Overeem Avatar asked May 30 '16 11:05

Michiel Overeem


People also ask

What is difference between CancellationTokenSource and CancellationToken?

The CancellationTokenSource is the 'thing' that issues the cancellation, for whatever reason. It needs a way to 'dispatch' that cancellation to all the CancellationToken 's it has issued. That's how, for example, ASP.NET can cancel operations when a request is aborted.

What is the use of CancellationToken in C#?

A CancellationToken enables cooperative cancellation between threads, thread pool work items, or Task objects. You create a cancellation token by instantiating a CancellationTokenSource object, which manages cancellation tokens retrieved from its CancellationTokenSource. Token property.

How do I cancel my cancellation token?

When given a CancellationToken , you can create a new instance of the token source, assign it's token to the provided token, and cancel it. All other parties that can read this token will see that it's cancellation has been requested.


1 Answers

Short answer - both are fine. I'd use ThrowIfCancellationRequested because IMO it's the safer option. It's also more consistent - methods lower in the call chain can propagate cancellation via the exception.

Whenever an exception occurs in RunAsync, Service Fabric reports a transient fault (which means that the service is restarted without the instance/replica being recreated).

It gives special treatment for OperationCanceledException - if it was thrown by the cancellation token passed to the method, then the method is considered to have been successfully cancelled and no fault will be reported.

You can try this yourself by monitoring the Microsoft-ServiceFabric-Services ETW events.

like image 133
Eli Arbel Avatar answered Sep 28 '22 02:09

Eli Arbel