Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net core CancellationToken vs CancellationChangeToken_Asp.net Core_.net Core_Cancellation Token - Fatal编程技术网

Asp.net core CancellationToken vs CancellationChangeToken

Asp.net core CancellationToken vs CancellationChangeToken,asp.net-core,.net-core,cancellation-token,Asp.net Core,.net Core,Cancellation Token,CancellationToken和CancellationChangeToken之间有什么区别?我什么时候用哪一种 似乎它们可以用于同样的目的。我缺少什么?CancellationChangeToken实现了IChangeToken,它的构造函数采用了一个CancellationToken参数 我想说的是,它能够在使用相同的令牌时,同时使用期望IChangeToken的方法和期望CancellationToken的方法 下面是一个来自 var firstCancellationTokenSou

CancellationToken
CancellationChangeToken
之间有什么区别?我什么时候用哪一种


似乎它们可以用于同样的目的。我缺少什么?

CancellationChangeToken
实现了
IChangeToken
,它的构造函数采用了一个
CancellationToken
参数

我想说的是,它能够在使用相同的令牌时,同时使用期望
IChangeToken
的方法和期望
CancellationToken
的方法

下面是一个来自

var firstCancellationTokenSource=新的CancellationTokenSource();
var secondCancellationTokenSource=新的CancellationTokenSource();
var firstCancellationToken=firstCancellationTokenSource.Token;
var secondCancellationToken=secondCancellationTokenSource.Token;
var firstCancellationChangeToken=新的CancellationChangeToken(firstCancellationToken);
var secondCancellationChangeToken=新的CancellationChangeToken(secondCancellationToken);
var compositeChangeToken=
新CompositeChangeToken(
新名单
{
firstCancellationChangeToken,
secondCancellationChangeToken
});
在这里,构造函数获取
IChangeToken
列表的
CompositeChangeToken
,用两个
CancellationToken
实例化。如果没有
CancellationChangeToken
类,这是不可能的。

简短回答:
CancellationChangeToken
CancellationToken
的薄包装,它通过
HasChanged
属性公开令牌的取消状态

由于
CancellationChangeToken
实现了
IChangeToken
接口,因此它可以传递给对令牌更改做出反应的任何对象,例如
IMemoryCache
:每个缓存项都可以设置为在一组特定条件下过期,这些条件由
IChangeToken
实例抽象。例如,这些条件可能是配置更改,或用户的显式无效请求

CancellationChangeToken
包装可以传递给一个或多个缓存项,以便在取消时将它们逐出。开发者也可以决定直接使用
CancellationToken
;然而,与通过
IChangeToken
进行的抽象相比,这将使内部逻辑和外部API变得复杂,因为IChangeToken非常干净、可扩展,并且工作正常


长答覆: 接口
IChangeToken
定义跟踪某种令牌的方法,检查它是否已更改(
HasChanged
),并可能在更改后自动触发一些回调

IChangeToken
有多种实现方式;例如,它们跟踪文件或配置选项

CancellationChangeToken
的作用是什么 A快速显示
CancellationChangeToken
是一个精简的
IChangeToken
包装
CancellationToken

public bool HasChanged=>Token.iscancellationrequest;
因此,其“更改”状态直接对应于基础令牌的取消状态

乍一看,这似乎很奇怪:一个
CancellationToken
已经存在,那么为什么要引入一个公开更少功能的包装器呢

实际上,至少有一个用例需要一种观察令牌状态的抽象方法:

缓存 NET内核提供了不同的缓存方式;这里我将使用它作为一个例子,它提供了一个简单的基于内存的键/值缓存,并且可以用最少的努力来使用

为了减少每个请求对性能的影响,缓存频繁需要的、昂贵的计算是有意义的。但是,我们需要一种跟踪活动缓存项的方法,以便在它们过时时立即将其逐出。问题是,缓存项可能具有非常不同的过时条件,例如,它们取决于配置值或本地文件(并且需要在这些配置值或本地文件更改后立即更新),或者具有定期超时

IChangeToken
接口提供了一种简单的方法来抽象这些逐出条件,这样缓存只需检查给定的
IChangeToken
对象的状态,而不必直接查看文件、计时器等。缓存甚至可能注册回调,这样令牌状态的更改直接触发逐出逻辑,因此不需要轮询

回到我们的
CancellationChangeToken
CancellationToken
允许设置延迟,直到它被自动取消,因此在使用
CancellationChangeToken
包装它之后,我们可以将其传递到缓存条目以进行自动逐出:

public IActionResult Index()
{
if(!\u memoryCache.TryGetValue(“entry1”,out DateTime cachedValue))
{
cachedValue=DateTime.Now;
var cacheOptions=new MemoryCacheEntryOptions()
.AddExpirationToken(新的CancellationChangeToken(新的CancellationTokenSource(5000).Token));
_memoryCache.Set(“entry1”,cachedValue,cacheOptions);
}
返回视图(“索引”,cachedValue);
}
在本例中,我们缓存当前时间戳。5秒后,取消令牌被取消,时间戳被收回

但是,这还不能证明使用
CancellationToken
是合理的,因为
IMemoryCache
已经提供了一种通过设置过期时间的方法

现在我们了解了基于代币的驱逐的真正优势:我们可以

  • 将多个
    IChangeToken
    实例合并为一个,从而在这些实例中的任何一个发生更改时退出缓存项
  • 使用相同的令牌
    var firstCancellationTokenSource = new CancellationTokenSource();
    var secondCancellationTokenSource = new CancellationTokenSource();
    
    var firstCancellationToken = firstCancellationTokenSource.Token;
    var secondCancellationToken = secondCancellationTokenSource.Token;
    
    var firstCancellationChangeToken = new CancellationChangeToken(firstCancellationToken);
    var secondCancellationChangeToken = new CancellationChangeToken(secondCancellationToken);
    
    var compositeChangeToken = 
        new CompositeChangeToken(
            new List<IChangeToken> 
            {
                firstCancellationChangeToken, 
                secondCancellationChangeToken
            });