PlanetLotus PlanetLotus - 1 month ago 16
C# Question

Why is this CancellationToken getting cancelled?

It seems like right after I call my first async method (

GetBar()
in this example), the CancellationToken's
IsCancellationRequested
is set to true, but I don't want that and don't understand why it's happening.

This is in an Azure Cloud Service worker role, if that matters.

public class WorkerRole : RoleEntryPoint
{
private CancellationTokenSource cancellationTokenSource;
private Task runTask;

public override void Run()
{
this.cancellationTokenSource = new CancellationTokenSource();
this.runTask = Task.Run(() => Foo.Bar(this.cancellationTokenSource.Token), this.cancellationTokenSource.Token);
}

public override void OnStop()
{
this.cancellationTokenSource.Cancel();

try
{
this.runTask.Wait();
}
catch (Exception e)
{
Logger.Error(e, e.Message);
}

base.OnStop();
}

// ... OnStart omitted
}

public static class Foo
{
public static async Bar(CancellationToken token)
{
while (true)
{
try
{
token.ThrowIfCancellationRequested();

var bar = await FooService.GetBar().ConfigureAwait(false);

// Now token.IsCancellationRequested == true. Why? The above call does not take the token as input.
}
catch (OperationCanceledException)
{
// ... Handling
}
}
}
}


I've successfully used CancellationTokens once before in another project and I use a similar setup here. The only difference I'm aware of is that this is in an Azure Cloud Service. Any idea why
IsCancellationRequested
is getting set to true?

Answer

It appears OnStop was called while you where awaiting for FooService.GetBar() to complete. Perhaps add some form of logging to see if OnStop is called between the token.ThrowIfCancellationRequested(); and after the var bar = await ... returns to confirm.

That is what is causing the token to be canceled.