取消取消或公开取消方法?

时间:2017-07-22 17:25:49

标签: c# async-await cancellationtokensource

首选以下两个例子中的哪一个?

示例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();
    }
}

示例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";
        }
    }
}

或许只是两者兼而有之? 但是,我认为通过异步方法取消使用是非常普遍的做法。

1 个答案:

答案 0 :(得分:4)

You should accept a CancellationToken as an argument并允许OperationCanceledException传播:

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

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