5

When I cancel a Task, the await result still returns true for the IsCanceled Property. Seems something is going wrong.

Please advise. This is the code:

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();
}

When I hit the CancelButton and therefore trigger the CancelButton_Click method, the CallBack method is triggered. But... when I check myTaskToWaitFor.IsCanceled is always returns false and I get this info: Id = 1, Status = RanToCompletion, Method = "{null}". Why is the status not Cancelled or something?

When I use http://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken.throwifcancellationrequested.aspx

like this:

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));
}

I only get some errors in debug mode and the it seems the myTaskToWaitFor is actually cancelled, but the code doesn't continue (on continue the program is shut down due to the exception). Any thoughts? Kind regards,

Matthijs

Edit:

test with the TrowIfCancellationRequested was based on "When you call ThrowIfCancellationRequested on a CancellationToken which is canceled, it will throw an OperationCanceledException. The Task Parallel Library knows that this type of exception represents cancellation rather than a failure, and will treat it differently. For example, Task has a property called IsCanceled that automatically becomes true when an OperationCanceledException is thrown while executing an async method." From the book Async in C# 5.0 by Alex Davies.

That's why I thought I could expect myTaskToWaitFor.IsCancelled to return true and the code would continue.

4

1 回答 1

7

ThrowIfCancellationRequested()是由于观察取消而发出信号表明您存在的理想方式。这try在调用者处将自身显示为异常,但您可以通过catch在.awaitAggregateException

于 2013-09-11T10:37:21.027 回答