これは、操作が長いかどうかに関係なく、常にアクションにCancellationTokenを追加することをお勧めしますか?
現在、すべてのアクションに追加していますが、それが正しいか間違っているかはわかりません。
_[ApiController]
[Route("api/[controller]")]
public class DummiesController : ControllerBase
{
private readonly AppDbContext _dbContext;
public DummyController(AppDbContext dbContext)
{
_dbContext = dbContext;
}
[HttpGet("{id}")]
public async Task<ActionResult<Dummy>> GetAsync(int id, CancellationToken ct) // <<----- should I always do this?
{
var dummy = await _dbContext.Dummies.AsNoTracking().SingleOrDefaultAsync(e=>e.Id == id, ct);
if (dummy == null) return NotFound();
return dummy;
}
}
_
また、CancellationToken ct = default(CancellationToken)
を追加する必要がありますか?
外部リソースへの依存関係がある場合は、追加する価値があります。
データベースがビジーであるか、データベース接続に一時的なエラー処理/再試行ポリシーが設定されているとします。エンドユーザーがブラウザーで[停止]を押すと、キャンセルトークンは(コード内の)待機中の操作を適切にキャンセルするのに役立ちます。
通常の状況では長時間実行される性質についてはあまり考えませんが、理想的ではない状況での長時間実行される性質、たとえばAzureで実行していて、SQLデータベースが定期的なメンテナンスを受けており、エンティティフレームワークが再試行するように構成されている場合(エンティティフレームワークがキャンセルトークンに適切に応答することを想定)。
補足として:ポリー復元力フレームワークは、外部キャンセルからの再試行キャンセルを調整するための外部キャンセルトークンに対する優れたサポートを備えています。彼らのウィキは、キャンセルを調整するための素晴らしい目玉なので、一読に値します: https://github.com/App-vNext/Polly/wiki
CancellationToken ct = default(CancellationToken)
に関しては、コントローラーアクションよりもライブラリコードの方がおそらく価値があります。ただし、コントローラーを直接ユニットテストしているが、キャンセルトークンを渡したくない場合に便利です。 .netコアの WebHostBuilder testframework は、最近コントローラーアクションを直接テストするよりも簡単にテストできると言いました。
alwaysCancellationTokenをコントローラーアクションに追加する必要がありますか?
いいえ。あなたは常にそうするべきではありません。
ASP.NET Core MVCコントローラーでのCancellationTokensの使用
https://andrewlock.net/using-cancellationtokens-in-asp-net-core-mvc-controllers/
これが正しい動作かどうかは、アプリによって異なります。 リクエストが状態を変更する場合、メソッドの途中で実行を停止したくない場合があります。一方、リクエストに副次作用がない場合は、おそらく(おそらく高価な)アクションをできるだけ早く停止する必要があります。
したがって、以下のようなメソッド/アクションがある場合(簡略化)。
await ProcessOrder();
await UpdateInventory();
処理中に注文をキャンセルしたくない場合は、注文を完了できますが、ユーザーがトンネルを通過してインターネット接続が失われた場合、在庫は更新されません。
これは、操作がパターンのような作業単位(分散システムなど)に含まれず、取り消しを最小限に抑える必要がある場合に特に重要です。