web-dev-qa-db-ja.com

MVC / Web APIコントローラーでCancellationTokenを使用する必要がありますか?

非同期コントローラーにはさまざまな例があります。それらのいくつかは、メソッド定義でCancellationTokenを使用します。

public async Task<ActionResult> ShowItem(int id, CancellationToken cancellationToken)
{
    await Database.GetItem(id, cancellationToken);
    ...

しかし、他の例やVS2013のデフォルトのASP.NETプロジェクトでさえもCancellationTokenをまったく使用せず、それなしでも機能します。

public async Task<ActionResult> ShowItem(int id)
{
    await Database.GetItem(id);
    ...

コントローラーでCancellationTokenを使用する必要があるかどうか(およびその理由)は明らかではありません。

39
user1224129

あなたはそれを使うべきです。現時点で適用されるのは AsyncTimeoutがある場合 ですが、将来のMVC/WebAPIバージョンではトークンが「どちらかのタイムアウト」として解釈される可能性がありますまたはクライアントが切断されました」。

37
Stephen Cleary

これを使用できます

public async Task<ActionResult> MyReallySlowReport(CancellationToken cancellationToken)
{
    CancellationToken disconnectedToken = Response.ClientDisconnectedToken;
    using (var source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, disconnectedToken))
    {
        IEnumerable<ReportItem> items;
        using (ApplicationDbContext context = new ApplicationDbContext())
        {
            items = await context.ReportItems.ToArrayAsync(source.Token);
        }
        return View(items);
    }
}

here から取得。

6
Ram

ユーザーは、ブラウザの停止ボタンまたはリロードボタンを押すことにより、Webアプリへのリクエストをいつでもキャンセルできます。通常、アプリは、Kestrelがユーザーに送信しなくても、とにかく応答を生成し続けます。実行中のアクションメソッドが長い場合、リクエストがキャンセルされたことを検出し、実行を停止することができます。

これを行うには、CancelationTokenをアクションメソッドに挿入します。これは、リクエストのHttpContext.RequestAbortedトークンに自動的にバインドされます。通常どおり、このトークンのキャンセルを確認し、それをサポートする非同期メソッドに渡すことができます。要求がキャンセルされると、OperationCanceledExceptionまたはTaskCanceledExceptionがスローされます。

以下のリンクは、このシナリオを詳細に説明しています。

https://andrewlock.net/using-cancellationtokens-in-asp-net-core-mvc-controllers/

1
NidhinSPradeep