Erik Bäckman Erik Bäckman - 3 years ago 54
C# Question

Take a cancellationtoken or expose a method for cancellation?

Which one of the following two examples is preferred?

Example 1

public class Worker : IDisposable
{
private CancellationTokenSource tokenSource;

public string State { get; private set; }

public async Task StartWorkAsync()
{
tokenSource = new CancellationTokenSource();

this.State = "Working";
await Task.Delay(5000, tokenSource.Token);
}

public void StopWork()
{
this.tokenSource.Cancel();
this.State = "Stopped";
}

public void Dispose()
{
tokenSource?.Dispose();
}
}


Example 2

public class Worker
{
public string State { get; private set; }

public async Task StartWorkAsync(CancellationToken ctoken)
{
ctoken.ThrowIfCancellationRequested();

this.State = "Working";
try
{
await Task.Delay(5000, ctoken);
}
catch (AggregateException) when (ctoken.IsCancellationRequested)
{
this.State = "Stopped";
}
}
}


Or perhaps just both?
However, I assume that it's expect that it's common practice to take a cancellationtoken with an async method.

Answer Source

You should accept a CancellationToken as an argument and allow the OperationCanceledException to propagate:

public async Task StartWorkAsync(CancellationToken ctoken)
{
  ctoken.ThrowIfCancellationRequested();

  this.State = "Working";
  try
  {
    await Task.Delay(5000, ctoken);
  }
  catch (OperationCanceledException)
  {
    this.State = "Stopped";
    throw;
  }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download