任务IsCanceled是假的,而我取消了

use*_*122 5 c# task async-await cancellationtokensource

当我取消任务时,等待结果仍然为IsCanceled属性返回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();
}
Run Code Online (Sandbox Code Playgroud)

当我点击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));
}
Run Code Online (Sandbox Code Playgroud)

我只在调试模式下遇到一些错误,似乎myTaskToWaitFor实际上被取消了,但代码没有继续(继续程序由于异常而关闭).有什么想法吗?亲切的问候,

Matthijs

编辑:

与TrowIfCancellationRequested测试是基于" 当你调用ThrowIfCancellationRequested其上取消了的CancellationToken,它会抛出一个OperationCanceledException,任务并行库都知道,这种类型的异常的代表取消,而不是失败,并会特别对待.例如,Task有一个名为IsCanceled的属性,当执行异步方法时抛出OperationCanceledException时自动变为true. "来自Alex Davies的C#5.0中的Async一书.

这就是为什么我认为我可以期望myTaskToWaitFor.IsCancelled返回true并且代码将继续.

Mar*_*ell 7

ThrowIfCancellationRequested()是信号,你是现有的,由于观测取消的理想方式.这本身表现为在调用者的异常,但你可以通过具有搞定try/ catch各地await,并简单地检查原因有-无论是在工作,或者通过检查AggregateException.