dotnetcore中的IOptionsSnapshot<>的自动更新原理
1、首先讲讲ChangeToken.OnChange方法:
原理是给一个CancellationToken注册一个消费者委托,调用CancellationToken的Cancel的时候会调用这个CancellationToken中所有的委托 代码实现如下:
public static IDisposable OnChange(Func<IChangeToken> changeTokenProducer, Action changeTokenConsumer)
{
if (changeTokenProducer == null)
{
throw new ArgumentNullException("changeTokenProducer");
}
if (changeTokenConsumer == null)
{
throw new ArgumentNullException("changeTokenConsumer");
}
Action<object> callback = null;
callback = delegate(object s)
{
IChangeToken changeToken = changeTokenProducer();
try
{
changeTokenConsumer();
}
finally
{
changeToken.RegisterChangeCallback(callback, null);
}
};
return changeTokenProducer().RegisterChangeCallback(callback, null);
}
2、IOptions<> 生命周期为Singleton,初始化的时候配置就已经存入缓存,并且不再更新
3、IOptionsSnapshot<> 生命周期为Scope,初始化的时候会写入缓存,内容由OptionsMonitor提供,初始化OptionsMonitor的时候会给所有的IOtionsChangeTokenSource<T>对象的ChangeToken注册一个重载配置的方法代码如下
using (IEnumerator<IOptionsChangeTokenSource<TOptions>> enumerator = this._sources.GetEnumerator())
{
while (enumerator.MoveNext())
{
IOptionsChangeTokenSource<TOptions> source = enumerator.Current;
ChangeToken.OnChange(() => source.GetChangeToken(), delegate
{
this.InvokeChanged();
});
}
}
这里的source.GetChangeToken中的Token是从IConfigurationRoot中获取的,以下代码可以证明:
public class ConfigurationChangeTokenSource<TOptions> : IOptionsChangeTokenSource<TOptions>
{
private IConfiguration _config; /// <summary>
/// Constructor taking the IConfiguration instance to watch.
/// </summary>
/// <param name="config">The configuration instance.</param>
public ConfigurationChangeTokenSource(IConfiguration config)
{
if (config == null)
{
throw new ArgumentNullException("config");
}
this._config = config;
} /// <summary>
/// Returns the reloadToken from IConfiguration.
/// </summary>
/// <returns></returns>
public IChangeToken GetChangeToken()
{
return this._config.GetReloadToken();
}
}
这里的_config就是调用AddOptions.Config(...)方法的时候注册进去的,而ConfigurationRoot在初始化的时候,会把自己的ChangeToken的Reload事件注册到所有的IConfigurationProvider对象的ChangeToken,代码如下
public ConfigurationRoot(IList<IConfigurationProvider> providers)
{
if (providers == null)
{
throw new ArgumentNullException("providers");
}
this._providers = providers;
using (IEnumerator<IConfigurationProvider> enumerator = providers.GetEnumerator())
{
while (enumerator.MoveNext())
{
IConfigurationProvider p = enumerator.Current;
p.Load();
ChangeToken.OnChange(() => p.GetReloadToken(), delegate
{
this.RaiseChanged();
});
}
}
}
private void RaiseChanged()
{
//执行自身的_changeToken的OnReload事件并且重新初始化一个ConfigurationReloadToken
Interlocked.Exchange<ConfigurationReloadToken>(ref this._changeToken, new ConfigurationReloadToken()).OnReload();
}
这样就可以保证所有的ConfigurationProvider发生Reload的时候,IConfigurationRoot中的ChangeToken也会发生Reload事件。而我们的配置发生改变的时候,我们的ConfigurationProvider需要先更新Data数据,然后再触发他的Reload事件,就可以触发IConfigurationRoot的Reload事件,OptionsMonitor初始化的时候会给IConfigurationRoot的ChangeToken注册一个更新配置缓存的事件(前面说到过),所以OptionsMonitor就会更新配置缓存,然后下一次请求的时候创建的新IOptionsSnapshot<>接口对象就可以读取到更新之后的配置信息了
dotnetcore中的IOptionsSnapshot<>的自动更新原理的更多相关文章
- 浅析 .Net Core中Json配置的自动更新
Pre 很早在看 Jesse 的Asp.net Core快速入门的课程的时候就了解到了在Asp .net core中,如果添加的Json配置被更改了,是支持自动重载配置的,作为一名有着严重" ...
- 从源码中理解Spring Boot自动装配原理
个人博客:槿苏的知识铺 一.什么是自动装配 SpringBoot 定义了一套接口规范,这套规范规定:SpringBoot在启动时会扫描外部引用jar包中的META-INF/spring.factori ...
- .Net Core配置与自动更新
.Net Core 将之前Web.Config中的配置迁移到了appsettings.json文件中,并使用ConfigurationBuilder来读取这个配置文件.并可设置在配置文件变化以后,自动 ...
- Nacos 自动更新配置不生效问题
版本 Nacos 1.4.1 SpringCloud 2020.0.3 解决方案 bootstrap.properties 增加应用名配置即可 spring.application.name=serv ...
- 使用友盟进行apk的自动更新
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- [每日自动更新]Hillstone 山石网科 StoneOS ISP路由表配置文件
1.数据基于APNIC,准确有效 2.适用于StoneOS 4.0~5.5各版本 3.对APNIC数据进行路由聚合,实现最小子网 4.覆盖中国大陆地区电信.联通.移动三大运营商,长宽.电信通等二级运营 ...
- 关闭Win10自动更新
使用过Windows10系统的小伙伴们都清楚,在Windows10中强制开启了自动更新功能,我们无法通过常规的办法关闭自动更新功能,那么我们该怎么去关闭自动更新呢?欢迎速来围观我的经验啦. 工具/原料 ...
- nvidia驱动自动更新版本后问题解决 -- failed to initialize nvml: driver/library version mismatch
因为必须关闭桌面窗口, 建议另外一台电脑ssh连接操作 1. 卸载旧版本并关闭图形界面 sudo apt-get remove --purge nvidia-\* sudo service light ...
- Mysql自动更新字段时间
Mysql中更新某天数据可设置该条数据中的某个字段自动更新 ALTER TABLE `表名` MODIFY `字段名` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON U ...
随机推荐
- Macaca 自动化框架 [Python 系列]
介绍 Macaca是一套完整的自动化测试解决方案,基于node.js开发.由阿里巴巴公司开源: 地址:http://macacajs.github.io/macaca/ 特点: 同时支持PC端和移动端 ...
- 1232: [Usaco2008Nov]安慰奶牛cheer
1232: [Usaco2008Nov]安慰奶牛cheer Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 612 Solved: 431[Submi ...
- java深拷贝和浅拷贝
1.概念 java里的clone分为: A:浅复制(浅克隆): 浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. b:深复制(深克隆):深复制把要复制的对象所引用的对象都复制了一遍. Java中对 ...
- 自己做得一个用于直观观察css3 transform属性中的rotate 3D效果
这段代码还是非常简单,是看了一个老师的视频受的启发,也是调用了很多个函数,所以比较杂乱吧! <!DOCTYPE html><html lang="en">& ...
- C++移位运算符详解
移位运算符包括左移"<<"和右移">>" 左移运算符<<: 1.无符号 语法格式:需要移位的数字<<移位的次数n ...
- Docker建立本地Registry
从容器运行一个Registry # docker run -p : registry 查看yelinyuntest/static_web镜像 # docker images yelinyuntest/ ...
- suse安装svn服务端和客户端的使用
suse安装svn服务端 一. 安装服务端 配置网络安装源(suse11sp1为例) 新建11.1.repo11.1为软件源名称,可自定义文件并添加如下内容后保存 linux-e0xg:/etc/zy ...
- 一键部署Kubernetes高可用集群
三台master,四台node,系统版本为CentOS7 IP ROLE 172.60.0.226 master01 172.60.0.86 master02 172.60.0.106 master0 ...
- Redis中的master-slave&sentinel
redis安装 解压完成后可以看到INSTALL和README.md文件,查看以获取更多有用信息. 在README文件中可以获取到软件的安装步骤.以下安装步骤基于此. #step1 进入文件夹,执行编 ...
- jquery、js获取页面高度宽度等
jquery获取页面高度宽度 //获取浏览器显示区域(可视区域)的高度 : $(window).height(); //获取浏览器显示区域(可视区域)的宽度 : $(window).width(); ...