5

タスクをキャンセルすると、IsCanceled プロパティに対して await の結果が true を返します。何かがうまくいかないようです。

お知らせ下さい。これはコードです:

CancellationTokenSource _cancelLationToken = new CancellationTokenSource();

private async void Button_Click(object sender, EventArgs e)
{
    _cancelLationToken = new CancellationTokenSource();
    _cancelLationToken.Token.Register(theCallBack);
    var myTaskToWaitFor = Task.Factory.StartNew(() => WorkHard(_cancelLationToken.Token), _cancelLationToken.Token);
    await myTaskToWaitFor;

    int i=0;

    if(myTaskToWaitFor.IsCanceled)
        i = i; //breakpoint for debugging
    else
        i = i; //breakpoint for debugging <== always ends here... :-(
}

private void WorkHard(CancellationToken token)
{
    for(int i = 0; i < 100000000; i++)
        if(token.IsCancellationRequested)
            break;
        else
            Math.Acos(Math.Pow(i, i / 10000000));
}

public void theCallBack()
{
    //todo: do something
}

private void CancelButton_Click(object sender, EventArgs e)
{
    _cancelLationToken.Cancel();
}

CancelButton を押して CancelButton_Click メソッドをトリガーすると、CallBack メソッドがトリガーされます。しかし... myTaskToWaitFor.IsCanceled を確認すると、常に false が返され、次の情報が表示されます: Id = 1、Status = RanToCompletion、Method = "{null}"。ステータスがキャンセルされていないのはなぜですか?

http://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken.throwifcancellationrequested.aspxを使用する場合

このような:

private void WorkHard(CancellationToken token)
{
    for(int i = 0; i < 100000000; i++)
        if(token.IsCancellationRequested)
            token.ThrowIfCancellationRequested();
        else
            Math.Acos(Math.Pow(i, i / 10000000));
}

デバッグモードでエラーが発生するだけで、myTaskToWaitFor が実際にキャンセルされたように見えますが、コードは続行されません (続行すると、例外のためにプログラムがシャットダウンされます)。何かご意見は?敬具、

マティス

編集:

TrowIfCancellationRequested を使用したテストは、「キャンセルされた CancellationToken で ThrowIfCancellationRequested を呼び出すと、OperationCanceledException がスローされます。タスク並列ライブラリは、このタイプの例外が失敗ではなくキャンセルを表すことを認識しており、異なる方法で処理します。たとえば、 Task には、非同期メソッドの実行中に OperationCanceledException がスローされると自動的に true になる IsCanceled というプロパティがあります

これが、myTaskToWaitFor.IsCancelled が true を返し、コードが続行されることを期待できると考えた理由です。

4

1 に答える 1

7

これThrowIfCancellationRequested()は、キャンセルが観察されたために存在していることを知らせる理想的な方法です。これ呼び出し元で例外として表示されますが、try/catchの周りに/ をawait配置し、タスクで、またはAggregateException.

于 2013-09-11T10:37:21.027 に答える