为什么这个 CancellationToken 被取消了?
Why is this CancellationToken getting cancelled?
似乎就在我调用我的第一个异步方法(本例中为 GetBar()
)之后,CancellationToken 的 IsCancellationRequested
设置为 true,但我不希望这样,也没有这样做明白为什么会这样。
如果重要的话,这是 Azure 云服务工作者角色。
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
}
}
}
}
我之前在另一个项目中成功使用过一次 CancellationTokens,我在这里使用了类似的设置。我知道的唯一区别是这是在 Azure 云服务中。知道为什么 IsCancellationRequested
设置为 true 吗?
似乎在您等待 FooService.GetBar()
完成时调用了 OnStop
。也许添加某种形式的日志记录以查看是否在 token.ThrowIfCancellationRequested();
之间和 var bar = await ...
returns 之后调用 OnStop
以确认。
这就是导致令牌被取消的原因。
要解决问题,您需要确保the overridden Run
method does not return till the work is complete。
public override void Run()
{
this.cancellationTokenSource = new CancellationTokenSource();
this.runTask = Task.Run(() => Foo.Bar(this.cancellationTokenSource.Token), this.cancellationTokenSource.Token);
this.runTask.Wait(); //You may need a try/catch around it
}
似乎就在我调用我的第一个异步方法(本例中为 GetBar()
)之后,CancellationToken 的 IsCancellationRequested
设置为 true,但我不希望这样,也没有这样做明白为什么会这样。
如果重要的话,这是 Azure 云服务工作者角色。
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
}
}
}
}
我之前在另一个项目中成功使用过一次 CancellationTokens,我在这里使用了类似的设置。我知道的唯一区别是这是在 Azure 云服务中。知道为什么 IsCancellationRequested
设置为 true 吗?
似乎在您等待 FooService.GetBar()
完成时调用了 OnStop
。也许添加某种形式的日志记录以查看是否在 token.ThrowIfCancellationRequested();
之间和 var bar = await ...
returns 之后调用 OnStop
以确认。
这就是导致令牌被取消的原因。
要解决问题,您需要确保the overridden Run
method does not return till the work is complete。
public override void Run()
{
this.cancellationTokenSource = new CancellationTokenSource();
this.runTask = Task.Run(() => Foo.Bar(this.cancellationTokenSource.Token), this.cancellationTokenSource.Token);
this.runTask.Wait(); //You may need a try/catch around it
}