Eknoes
Eknoes

Reputation: 359

Cancel Task from inside the task

I'm using parse.com for authentication. When a user is authenticated i want to load some data from parse, but this should only happen when authentication was successful. I try to cancel the task with a CancellationToken, but it does not work. Here is the example code:

CancellationTokenSource cts = new CancellationTokenSource();

ParseUser.LogInAsync(username, password).ContinueWith(t =>
{
    if (t.IsFaulted || t.IsCanceled)
    {
        // Login failed
        cts.Cancel();
    }

    return t;
}, cts.Token).Unwrap().ContinueWith(t =>
{
    return LoadDataAsync();
}).Unwrap().ContinueWith(t =>
{
    LoginSuccessful();
})

Is it possible to cancel the task like this? Or what am i doing wrong?

Upvotes: 1

Views: 1063

Answers (1)

i3arnon
i3arnon

Reputation: 116548

First of all, you should really consider using async-await instead of ContinueWith. Your code would be much simpler:

await ParseUser.LogInAsync(username, password);
await LoadDataAsync();
LoginSuccessful();

Cancellation in .net is cooperative so someone cancels the token (usually outside of the task) and the code inside the task needs to observe the token. Your code doesn't observe the token so it can only cancel the task if it's canceled before the task starts executing (which can't be the case when the task cancels itself).

You need to observe the token and throw if cancellation was requested:

if (t.IsFaulted || t.IsCanceled)
{
    // Login failed
    cts.Cancel();
    cts.Token.ThrowIfCancellationRequested();
}

Upvotes: 5

Related Questions