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 ...
随机推荐
- java-信息安全(二)-对称加密算法DES,3DES,AES,Blowfish,RC2,RC4
概述 信息安全基本概念: DES(Data Encryption Standard,数据加密标准) 3DES(Triple DES,三重数据加密算法(TDEA,Triple Data Encrypti ...
- 2659: [Beijing wc2012]算不出的算式
2659: [Beijing wc2012]算不出的算式 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 757 Solved: 425[Submit] ...
- 《Django By Example》第九章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者@ucag 注:哈哈哈,第九章终于来啦 ...
- 新学期的第一节Android课
老师问,你们认为师生关系是什么样子的? 机智的我很快想到啦:或许是猫和老鼠的关系吧,嘿嘿O(∩_∩)O
- webpack和webpack-dev-server安装配置(遇到各种问题的解决方法)
跟着Webpack傻瓜式指南(一)这个教程在安装webpack和webpack-dev-server的时候遇到很多问题,查了很多终于一一找到解决办法. 主要参考了这三篇博文: moudule.js:3 ...
- Linux实战教学笔记25:自动化运维工具之ansible (一)
第二十五节 ansible之文件的批量分发 标签(空格分隔): Linux实战教学笔记-陈思齐 ---本教学笔记是本人学习和工作生涯中的摘记整理而成,此为初稿(尚有诸多不完善之处),为原创作品,允许转 ...
- Python自动生产表情包
作为一个数据分析师,应该信奉一句话--"一图胜千言".不过这里要说的并不是数据可视化,而是一款全民向的产品形态--表情包!!!! 表情包不仅仅是一种符号,更是一种文化--是促进社交 ...
- JavaScript高级程序设计(学习)
文档模式是:混杂模式和标准模式. 若在文档开始处没有文档类型声明,则浏览器就会开启混杂模式.这种模式在不同的浏览器下行为差异非常大,如果不使用某些hack技术,跨浏览器的行为根本就没有一致性可言. 局 ...
- java安装1335错误解决办法(亲测)
心血来潮想了解一下java,结果一开始就碰到了让心"恶心"的1335错误. 废话不多说,直接看下面: 你可以先尝试在这个链接下载java.exe文件 http://www.orac ...
- ECMAScript6-let和const命令
▓▓▓▓▓▓ 大致介绍 ES6是下一代的JavaScript语言的标准,目标是让JavaScript可以用来编写大型的复杂程序,成为企业级开发语言,要查看浏览器对ES6的支持程度可以用阮一峰大佬写的工 ...