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<>的自动更新原理的更多相关文章

  1. 浅析 .Net Core中Json配置的自动更新

    Pre 很早在看 Jesse 的Asp.net Core快速入门的课程的时候就了解到了在Asp .net core中,如果添加的Json配置被更改了,是支持自动重载配置的,作为一名有着严重" ...

  2. 从源码中理解Spring Boot自动装配原理

    个人博客:槿苏的知识铺 一.什么是自动装配 SpringBoot 定义了一套接口规范,这套规范规定:SpringBoot在启动时会扫描外部引用jar包中的META-INF/spring.factori ...

  3. .Net Core配置与自动更新

    .Net Core 将之前Web.Config中的配置迁移到了appsettings.json文件中,并使用ConfigurationBuilder来读取这个配置文件.并可设置在配置文件变化以后,自动 ...

  4. Nacos 自动更新配置不生效问题

    版本 Nacos 1.4.1 SpringCloud 2020.0.3 解决方案 bootstrap.properties 增加应用名配置即可 spring.application.name=serv ...

  5. 使用友盟进行apk的自动更新

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  6. [每日自动更新]Hillstone 山石网科 StoneOS ISP路由表配置文件

    1.数据基于APNIC,准确有效 2.适用于StoneOS 4.0~5.5各版本 3.对APNIC数据进行路由聚合,实现最小子网 4.覆盖中国大陆地区电信.联通.移动三大运营商,长宽.电信通等二级运营 ...

  7. 关闭Win10自动更新

    使用过Windows10系统的小伙伴们都清楚,在Windows10中强制开启了自动更新功能,我们无法通过常规的办法关闭自动更新功能,那么我们该怎么去关闭自动更新呢?欢迎速来围观我的经验啦. 工具/原料 ...

  8. nvidia驱动自动更新版本后问题解决 -- failed to initialize nvml: driver/library version mismatch

    因为必须关闭桌面窗口, 建议另外一台电脑ssh连接操作 1. 卸载旧版本并关闭图形界面 sudo apt-get remove --purge nvidia-\* sudo service light ...

  9. Mysql自动更新字段时间

    Mysql中更新某天数据可设置该条数据中的某个字段自动更新 ALTER TABLE `表名` MODIFY `字段名` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON U ...

随机推荐

  1. 如何理解jQuery中的ajaxSubmit方法

    版权声明:本文为博主原创文章,转载请标注:www.cnblogs.com/gdsblog 刚刚学习中,使用到了ajaxSubmit,犹豫以前没有接触㢧这个,所以刚开始是一脸懵逼状态,最后通过查找资料的 ...

  2. HTTPS 为什么更安全,先了解一下密码学的这些原理

    HTTPS 是建立在密码学基础之上的一种安全通信协议,严格来说是基于 HTTP 协议和 SSL/TLS 的组合.理解 HTTPS 之前有必要弄清楚一些密码学的相关基础概念,比如:明文.密文.密码.密钥 ...

  3. Python round() 函数

    round() 方法返回浮点数x的四舍五入值. 以下是 round() 方法的语法: round( x [, n] )x为浮点数,n为保留的小数点位. 以下展示了使用 round() 方法的实例: p ...

  4. fprintf&prinft&sprintf

    1: fprintf()#include <stdio.h> int fprintf( FILE *stream, const char *format, ... );fprintf()函 ...

  5. 【NFS项目实战二】NFS共享数据的时时同步推送备份

    [NFS项目实战二]NFS共享数据的时时同步推送备份 标签(空格分隔): Linux服务搭建-陈思齐 ---本教学笔记是本人学习和工作生涯中的摘记整理而成,此为初稿(尚有诸多不完善之处),为原创作品, ...

  6. RabbitMQ-从基础到实战(2)— 防止消息丢失

    转载请注明出处 1.简介 RabbitMQ中,消息丢失可以简单的分为两种:客户端丢失和服务端丢失.针对这两种消息丢失,RabbitMQ都给出了相应的解决方案. 2.防止客户端丢失消息 如图,生产者P向 ...

  7. 联想A7600-m刷机心得

    先来说说刷机 联想A7600-m的刷机

  8. Linux环境Perl链接MS Sql Server数据库

    1.下载相关软件 unixODBC.freetds和DBD-ODBC ①.Linux系统的ODBC unixODBC-2.3.4.tar.gz ( http://www.unixodbc.org) ② ...

  9. datatables,表格

    官方文档:https://datatables.net/ var dttblTaskOrderOptions={ order: [5, 'desc'], ajax:{ url:"order/ ...

  10. javaWEB与Session

    HttpSession(*****)1. HttpSession概述  * HttpSession是由JavaWeb提供的,用来会话跟踪的类.session是服务器端对象,保存在服务器端!!!  * ...