4

CancellationTokenIsCancellationRequestedプロパティの用途は何ですか? 以下のコードを検討してください

static void Main(string[] args)
{
    CancellationTokenSource tokenSource = new CancellationTokenSource();
    var token = tokenSource.Token;
    Console.WriteLine("Press Enter to Start.\nAgain Press enter to finish.");
    Console.ReadLine();
    Task t = new Task(() =>
    {
        int i = 0;
        while (true)
        {
            if (token.IsCancellationRequested)
            {
                Console.WriteLine("Task Cancel requested");
                break;
            }
            Console.WriteLine(i++);
        }
    }, token);

    t.Start();

    // wait for input before exiting
    Console.ReadLine();
    tokenSource.Cancel();
    if(t.Status==TaskStatus.Canceled)
        Console.WriteLine("Task was cancelled");
    else
        Console.WriteLine("Task completed");
}

まれに、ifブロック内のコードが実行されないことがあります。もしそうなら、キャンセルが要求されているかどうかを確認するためのポーリングの使用は何ですか?

4

1 に答える 1

7

コードの問題は、 が終了するのを待たないことですTask。したがって、何が起こるかは次のとおりです。

  1. を呼び出しますCancel()
  2. をチェックするStatusと、 が返されますRunning
  3. Task紛らわしいことに、まだ実行中のときに「タスクが完了しました」と書きます。
  4. Main()完了すると、アプリケーションは終了します。
  5. (この時点でIsCancellationRequested、バックグラウンド スレッドからチェックされます。しかし、アプリケーションが既に終了しているため、それは起こりません。)

これを修正するには、t.Wait()を呼び出した後に追加しますCancel()

しかし、それでもプログラムを完全に修正することはできません。Taskキャンセルされたことを伝える必要があります。OperationCanceledExceptionそして、 を含むをスローすることでそれを行いますCancellationToken(これを行う通常の方法は、 を呼び出すことですThrowIfCancellationRequested())。

これに関する 1 つの問題は、キャンセルさWait()れた a を ing するとTask例外がスローされるため、それをキャッチする必要があることです。

于 2013-02-23T10:46:17.537 に答える