gpt4 book ai didi

c# - Service Fabric RunAsync(CancellationToken cancellationToken) 没有被取消

转载 作者:太空狗 更新时间:2023-10-30 00:49:12 27 4
gpt4 key购买 nike

我认为 RunAsync 方法采用 CancellationToken 作为参数,这很棒。 不幸的是,根据我的观察,我从未被取消。

当然,取消RunAsync 方法调用OnCloseAsync 会有点多余。 我仍然想知道什么时候(如果)取消真的发生了。

我是否应该编写一些额外的代码来在我的客户端中提供一个有效的 Stop() 方法?我更希望 RunAsync 中的 cancellationToken 实际上被取消 ;-)

我的服务架构服务代码:

/// <summary>
/// This is the main entry point for your service instance.
/// </summary>
/// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service instance.</param>
protected override async Task RunAsync(CancellationToken cancellationToken)
{
// TODO: Replace the following sample code with your own logic
// or remove this RunAsync override if it's not needed in your service.

long iterations = 0;

while (!cancellationToken.IsCancellationRequested)
{
// I commented this out because I want my client to handle the cancellation
// event gracefully without throwing an OperationCanceled exception.
//cancellationToken.ThrowIfCancellationRequested();

// I never found these messages in any logs. Nor in the diagnostics events window in Visual Studio.
ServiceEventSource.Current.ServiceMessage(this, "Working-{0}", ++iterations);

await _client.Start(cancellationToken);

await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
}
}

我的示例客户端实现:

public class Client
{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();

public async Task Start(CancellationToken cancellationToken = default(CancellationToken))
{
while (!cancellationToken.IsCancellationRequested)
{
_logger.Info("Saying hello from Main Operation.");
await Task.Delay(3000, cancellationToken);
}

_logger.Info("Cancellation requested. Shutting down MainOperation().");
}

public void Stop()
{
_logger.Info("Stop requested. But I have no means to stop. Not implemented.");
}
}

最佳答案

是的,取消 token 实际上被取消了。这是有保证的。我可以向您保证,经过多年的测试和生产使用,这不是疏忽。

但是您的代码中存在疏忽。

如果您希望从您的客户端看到此跟踪输出:

 _logger.Info("Cancellation requested. Shutting down MainOperation().");

你不会,而是极不可能你永远不会看到它。为什么?因为它之前的这一行:

await Task.Delay(3000, cancellationToken);

在延迟期间发出取消 token 信号时,将抛出 OperationCanceledException。这会将您踢出循环并退出 RunAsync,因此您的日志行将不会执行。

由于您在该延迟中花费了 3 秒,而在循环之外花费了纳秒,您可以理解为什么当您不在延迟内时取消发生的可能性极小。

关于c# - Service Fabric RunAsync(CancellationToken cancellationToken) 没有被取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39609918/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com