【问题标题】:Is it safe to call CancellationTokenSource.Cancel multiple times?多次调用 CancellationTokenSource.Cancel 是否安全?
【发布时间】:2018-10-15 21:22:15
【问题描述】:

例如,如果我想取消Dispose() 调用(其中can be called multiple times)中的某些操作,那么我需要写吗

public void Dispose()
{
    if (!cancellationTokenSource.IsCancellationRequested)
    {
        cancellationTokenSource.Cancel();
    }
}

或者简单一点就够了

public void Dispose()
{
    cancellationTokenSource.Cancel();
}

(欢迎您评论在 Dispose 方法中取消事物是否明智,但这不是这个问题的重点。)

【问题讨论】:

    标签: c# cancellationtokensource


    【解决方案1】:

    是的。

    但前提是 CancellationTokenSource 尚未被处置。

    来自reference source

    ThrowIfDisposed();
    
    // ...
    
    // fast-path test to check if Notify has been called previously
    if (IsCancellationRequested)
        return;
    

    【讨论】:

      【解决方案2】:

      这似乎更多是关于 Dispose 模式的问题,然后是关于 CancellationToken 或其他任何东西的问题。而且我不确定您是否正确实施了上述模式。这是有关该材料的官方 MS 文档: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern

      这里是我的解释:

      Disposing 有两个级别:Dispose 和 Finalizsation。由于两者的代码非常相似,因此通常将它们组合成一个函数(在 C# 中通常是 Dispose 一个)。主要区别在于是否将其中继到包含的类。您总是中继 Dispose 调用(中继通常是 Dispose 的目的)。您永远不会中继终结调用(终结仅在该实例和 GC 之间进行)。

      还有两种情况:一种是直接处理非托管资源。还有一个你只处理另一个 Disposeable 类。

      直接未管理的资源

      在这种情况下,您要做的第一件事是实现终结器,因此至少 GC 可以可靠地清理它。然后你将 IDisposeable 实现为一个附加功能,这样程序员就可以使用 using 模式之类的东西在运行时清理确定性。

      处理实现 IDisposeable 的东西

      您有一个实现 IDisposeable 的资源(比如文件流引用)。您在类中实现 IDisposeable 的唯一目的是将 Dispose() 调用中继到所述 FileStream。这种方式比较常见的情况。它会猜测它大约占所有 Dispose 实现的 95-99%。

      这里要记住的一件事是,“Dispose”和“Finalize”通常意味着较低级别的清理。您调用 dispose 的 SQLConenction 将首先关闭(如果需要)。您 Dispose 关闭的 Filehandle 也将首先关闭。即使调用cancellationTokenSource.Cancel 是不可重复的,cancellationTokenSource.Dispose 也应该调用 Cancel 作为其操作的一部分并且应该是可重复的。该类本身确实实现了 IDisposeable。如果有任何类这样做,通常只需调用 Dispose 而不是通过 Cancel 手动进行清理:https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource?view=netframework-4.7.2

      【讨论】:

      • Dispose 只是一个例子,没有它可以改写问题。关于调用 Dispose 而不是 Cancel:在这种情况下它不起作用,因为 Dispose 不会调用注册的回调,不是线程安全的(与 Ca​​ncel 相反),并且如果 CTS 也被其他人取消,或者以其他方式使用,它会导致 ObjectDisposedExceptions。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-18
      • 2018-09-20
      • 1970-01-01
      • 2014-06-15
      相关资源
      最近更新 更多