我看到微软为异步方法强制执行此模式:

async Task<object> DoMyOperationAsync(int par1, string par2,..., CancellationToken token=default(CancellationToken))
{
   ...
   CancellationToken.ThrowIfRequested();
   ...
}

每个方法都应该有那个丑陋的 CancellationToken token=default(CancellationToken) 参数,即使大多数时候它甚至没有被使用,但充其量只是通过了。

为什么我们不能只使用某种 CancellationTokenContext 而不是这个,并在实际需要它的方法中使用它?
public class CancellationTokenContext
{
    static AsyncLocal<CancellationToken> asyncContext = new AsyncLocal<CancellationToken>();

    public static CancellationToken Current {
        get {
            return asyncContext.Value;
        }
        set {
            asyncContext.Value = value;
        }
    }

    public static void ThrowIfRequested() {
        Current.ThrowIfCancellationRequested();
    }
}


public class MyClassWithAsyncMethod{

    public async Task<object> DoMyOperationAsync(int par1, string par2,...)
    {
        ...
        CancellationTokenContext.ThrowIfRequested();
        ...
    }

}

最佳答案

不使用 AsyncLocal 的主要原因是它要慢得多。事实上,这是一个字典查找,所以它应该慢大约 20 倍(~20ns vs 1ns)。

另一个因素是:显式通常比隐式更好。尽管我同意这是异步实现中非常烦人的部分。

关于c# - CancellationToken : why not to use AsyncLocal context instead of passing parameter to every async method?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57366410/

10-11 05:46