我认为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.");
}
}
答案 0 :(得分:5)
是的,取消令牌实际上已取消。这是有保证的。我可以向您保证,经过多年的测试和生产使用,这不是一种疏忽。
然而,您的代码存在疏忽。
如果您希望从客户端看到此跟踪输出:
_logger.Info("Cancellation requested. Shutting down MainOperation().");
你不会,而不是非常你不可能看到它。为什么?因为之前的这一行:
await Task.Delay(3000, cancellationToken);
在延迟期间发出取消令牌信号时,将抛出OperationCanceledException 。这将使您退出循环并退出RunAsync,因此您的日志记录行将不会执行。
由于您在该延迟中花费3秒钟,并且在循环中花费超过纳秒,您可以看到为什么当您不在延迟内部时取消将极不可能发生。