2016-09-21 26 views
2

我想RunAsync方法需要CancellationToken作为一个很好的参数。 不幸的是,我的观察我永远不会被取消。服务结构RunAsync(CancellationToken cancellationToken)不会被取消

当然取消RunAsync方法调用OnCloseAsync将是一种多余。 我还想知道何时(如果)取消实际发生。

我应该写一些额外的代码来提供一个工作的Stop()方法在我的客户端?我会在者优先中的CancellationToken将RunAsync实际上被取消;-)

我的服务织物服务代码:

/// <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

再次,执行此操作的一种方法是使用DeleteServiceAsync以编程方式删除服务,使用DeleteServiceAsync也可以使用CreateServiceAsync重新创建它。 – LoekD

+0

当然。但我不想在Service Fabric之外运行任何代码。 OnCloseAsync也被调用,这很好。我可以与此合作。我仍然想知道RunAsync的cancellationToken是否被设置为“取消”。 – lapsus

+0

你可以从其他服务中调用它。当服务停止,升级,从辅助副本迁移到主副本和/或在群集中重新定位时调用。 – LoekD

回答

3

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

但是,您的代码中存在疏漏。

如果你期待看到从客户端此跟踪输出:

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

你不会,相反,它是非常你可能不再看到它。为什么?因为该行之前:

await Task.Delay(3000, cancellationToken); 

掷OperationCanceledException当延迟期间取消标记的信号。这会将你踢出循环并退出RunAsync,所以你的记录行将不会执行。

由于您在该延迟中花费了3秒,并且在循环之外花了3秒,您可以看到为什么当您不在延迟范围内时发生取消的可能性极小。

+2

* facepalm *你是对的...... – lapsus

+0

如果服务结构包含带有CancellationToken的'RunAsync',为什么会有'CloseAsync'?你知道什么时候该服务正在通过“RunAsync”右侧的CancellationToken关闭? –

相关问题