ASP.NET Core'de değişiklik belirteçleriyle değişiklikleri ASP.NET Core

Değişiklik belirteci, durum değişikliklerini izlemek için kullanılan genel amaçlı, düşük düzeyli bir yapı taşıdır.

Örnek kodu görüntüleme veya indirme ( nasılindir)

IChangeToken arabirimi

IChangeToken bir değişikliğin meydana geldiği bildirimleri yalıtır. IChangeToken ad alanı içinde Microsoft.Extensions.Primitives yer almaktadır. Microsoft.Extensions.Primitives NuGet paketi, uygulama uygulamalarına ASP.NET Core sağlanır.

IChangeToken iki özelliği vardır:

  • ActiveChangeCallbacks belirteci proaktif olarak geri çağırmaları yükseltin. olarak ActiveChangedCallbacks false ayarlanırsa, hiçbir zaman bir geri çağırma çağrılamaz ve uygulamanın değişiklikleri HasChanged yoklaması gerekir. Hiçbir değişiklik oluşmazsa veya temel alınan değişiklik dinleyicisi atılabilir veya devre dışı bırakılırsa belirteç hiçbir zaman iptal edilemez.
  • HasChanged bir değişiklik olup ola bir değer alır.

Arabirimi, belirteç değiştirilmeden önce çağrılan bir geri çağırmayı kaydeden IChangeToken RegisterChangeCallback(Action <Object> , Object) yöntemini içerir. HasChanged geri çağırma çağrılmadan önce ayar gerekir.

ChangeToken sınıfı

ChangeToken , bir değişikliğin meydana geldiği bildirimleri yaymada kullanılan statik bir sınıftır. ChangeToken ad alanı içinde Microsoft.Extensions.Primitives yer almaktadır. Microsoft.Extensions.Primitives NuGet paketi, uygulama uygulamalarına ASP.NET Core sağlanır.

ChangeToken.OnChange(Func <IChangeToken> , Action) yöntemi, belirteç her Action değiştirilse çağrısı yapmak için bir kaydettirmektedir:

  • Func<IChangeToken> belirteci üretir.
  • Action belirteç değişirken çağrılır.

ChangeToken.OnChange <TState> (Func <IChangeToken> , Action , <TState> TState) aşırı yüklemesi, belirteç tüketicisine geçirilen TState ek bir parametre Action alır.

OnChange bir IDisposable döndürür. çağrısı, Dispose belirteci diğer değişiklikleri dinlemeyi durdurur ve belirteci kaynakları serbest bıraktır.

Verilerde değişiklik belirteçlerinin örnek kullanımları ASP.NET Core

Değişiklik belirteçleri, nesnelerin değişikliklerini izlemek ASP.NET Core önemli bölgelerde kullanılır:

  • Dosyalarda yapılan değişiklikleri izlemek IFileProvider için Watch yönteminin izlemesi IChangeToken için belirtilen dosya veya klasör için bir oluşturur.
  • IChangeToken belirteçler, değişiklik üzerine önbellek çıkarmalarını tetiklemek için önbellek girişlerine eklenebilir.
  • Değişiklikler TOptions için, varsayılan OptionsMonitor<TOptions> uygulamasının bir veya daha fazla örneği kabul eden bir aşırı IOptionsMonitor<TOptions> IOptionsChangeTokenSource<TOptions> yüklemesi vardır. Her örnek, seçenek IChangeToken değişikliklerini izlemek için bir değişiklik bildirimi geri aramasını kaydetmek için bir döndürür.

Yapılandırma değişikliklerini izleme

Varsayılan olarak, ASP.NET Core uygulama yapılandırma ayarlarını yüklemek için JSON yapılandırma dosyalarını ( ,appsettings.Development.jsve appsettings.json üzerinde appsettings.Production.js) kullanır.

Bu dosyalar, üzerinde parametre kabul eden AddJsonFile(IConfigurationBuilder, String, Boolean, Boole) uzantı yöntemi ConfigurationBuilder kullanılarak reloadOnChange yapılandırılır. reloadOnChange , yapılandırmanın dosya değişikliklerinde yeniden yükleniyor olması gerektiğini belirtir. Bu ayar kolaylık Host yönteminde CreateDefaultBuilder görünür:

config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, 
          reloadOnChange: true);

Dosya tabanlı yapılandırma ile temsil FileConfigurationSource edildi. FileConfigurationSource , IFileProvider dosyaları izlemek için kullanır.

Varsayılan olarak, IFileMonitor yapılandırma dosyası değişikliklerini izlemek için kullanan PhysicalFileProvider bir tarafından FileSystemWatcher sağlanır.

Örnek uygulama, yapılandırma değişikliklerini izlemek için iki uygulamayı gösterir. Appsettings dosyalardan herhangi biri değişirse, her iki dosya izleme uygulaması da örnek uygulamanın konsola bir ileti yazdığı — özel kodu yürütür.

Bir yapılandırma dosyası, FileSystemWatcher tek bir yapılandırma dosyası değişikliği için birden çok belirteç geri çağırması tetikler. Özel kodun birden çok belirteç geri çağırma tetiklendiğinde yalnızca bir kez çalıştırlendiğinden emin olmak için, örneğin uygulaması dosya karmalarını denetler. Örnek, SHA1 dosya karması kullanır. Üstel geri kapatma ile yeniden deneme uygulanır. Dosyada yeni bir karmanın hesap işlemini geçici olarak engelleyen dosya kilitleme işlemi meydana gelebilir, çünkü yeniden deneme mevcuttur.

Utilities/Utilities.cs:

public static byte[] ComputeHash(string filePath)
{
    var runCount = 1;

    while(runCount < 4)
    {
        try
        {
            if (File.Exists(filePath))
            {
                using (var fs = File.OpenRead(filePath))
                {
                    return System.Security.Cryptography.SHA1
                        .Create().ComputeHash(fs);
                }
            }
            else 
            {
                throw new FileNotFoundException();
            }
        }
        catch (IOException ex)
        {
            if (runCount == 3 || ex.HResult != -2147024864)
            {
                throw;
            }
            else
            {
                Thread.Sleep(TimeSpan.FromSeconds(Math.Pow(2, runCount)));
                runCount++;
            }
        }
    }

    return new byte[20];
}

Basit başlangıç değişiklik belirteci

Yapılandırma yeniden yükleme Action belirteciğine yönelik değişiklik bildirimleri için belirteç tüketici geri çağırmasını kaydetme.

Startup.Configure içinde:

ChangeToken.OnChange(
    () => config.GetReloadToken(),
    (state) => InvokeChanged(state),
    env);

config.GetReloadToken() belirteci sağlar. Geri çağırma InvokeChanged yöntemidir:

private void InvokeChanged(IWebHostEnvironment env)
{
    byte[] appsettingsHash = ComputeHash("appSettings.json");
    byte[] appsettingsEnvHash = 
        ComputeHash($"appSettings.{env.EnvironmentName}.json");

    if (!_appsettingsHash.SequenceEqual(appsettingsHash) || 
        !_appsettingsEnvHash.SequenceEqual(appsettingsEnvHash))
    {
        _appsettingsHash = appsettingsHash;
        _appsettingsEnvHash = appsettingsEnvHash;

        WriteConsole("Configuration changed (Simple Startup Change Token)");
    }
}

geri çağırmanın , state izlenirken IWebHostEnvironment doğru appsettings yapılandırma dosyasını belirtmek için yararlıdır (örneğin, geliştirme ortamındaappsettings.Development.jsiçin) geçiş yapmak için kullanılır. Yapılandırma dosyası yalnızca bir kez değiştiriken birden çok belirteç geri çağırma nedeniyle deyimin birden çok kez çalıştırılamaması için WriteConsole dosya karmaları kullanılır.

Uygulama çalışır durumda olduğu sürece bu sistem çalışır ve kullanıcı tarafından devre dışı bırakılamaz.

Hizmet olarak yapılandırma değişikliklerini izleme

Örnek şunları uygulamaya almaktadır:

  • Temel başlangıç belirteci izleme.
  • Hizmet olarak izleme.
  • İzlemeyi etkinleştirme ve devre dışı bırakma mekanizması.

Örnek bir arabirim IConfigurationMonitor sağlar.

Extensions/ConfigurationMonitor.cs:

public interface IConfigurationMonitor
{
    bool MonitoringEnabled { get; set; }
    string CurrentState { get; set; }
}

Uygulanan sınıfının oluşturucusu, değişiklik ConfigurationMonitor bildirimleri için bir geri çağırmayı kaydettir:

public ConfigurationMonitor(IConfiguration config, IWebHostEnvironment env)
{
    _env = env;

    ChangeToken.OnChange<IConfigurationMonitor>(
        () => config.GetReloadToken(),
        InvokeChanged,
        this);
}

public bool MonitoringEnabled { get; set; } = false;
public string CurrentState { get; set; } = "Not monitoring";

config.GetReloadToken() belirteci sağlar. InvokeChanged , geri çağırma yöntemidir. stateBu örnekte, izleme durumuna IConfigurationMonitor erişmek için kullanılan örnek için bir başvuru. İki özellik kullanılır:

  • MonitoringEnabled: Geri çağırmanın özel kodunu çalıştırması gerektiğini gösterir.
  • CurrentState: Kullanıcı arabiriminde kullanmak üzere geçerli izleme durumunu açıklar.

yöntemi, InvokeChanged aşağıdakiler dışında önceki yaklaşıma benzer:

  • değilse kodunu MonitoringEnabled true çalıştırmaz.
  • Çıktıda geçerli state olan çıktıyı WriteConsole oluşturur.
private void InvokeChanged(IConfigurationMonitor state)
{
    if (MonitoringEnabled)
    {
        byte[] appsettingsHash = ComputeHash("appSettings.json");
        byte[] appsettingsEnvHash = 
            ComputeHash($"appSettings.{_env.EnvironmentName}.json");

        if (!_appsettingsHash.SequenceEqual(appsettingsHash) || 
            !_appsettingsEnvHash.SequenceEqual(appsettingsEnvHash))
        {
            string message = $"State updated at {DateTime.Now}";
          

            _appsettingsHash = appsettingsHash;
            _appsettingsEnvHash = appsettingsEnvHash;

            WriteConsole("Configuration changed (ConfigurationMonitor Class) " +
                $"{message}, state:{state.CurrentState}");
        }
    }
}

Bir örnek ConfigurationMonitor içinde hizmet olarak Startup.ConfigureServices kaydedilir:

services.AddSingleton<IConfigurationMonitor, ConfigurationMonitor>();

Dizin sayfası, kullanıcıya yapılandırma izleme üzerinde denetim sunar. örneği IConfigurationMonitor içine IndexModel girildi.

Pages/Index.cshtml.cs:

public IndexModel(
    IConfiguration config, 
    IConfigurationMonitor monitor, 
    FileService fileService)
{
    _config = config;
    _monitor = monitor;
    _fileService = fileService;
}

İzlemeyi etkinleştirmek veya devre dışı bırakmak ve kullanıcı arabirimi geri bildirimi için geçerli durumu ayarlamak için yapılandırma izleyicisi ( _monitor ) kullanılır:

public IActionResult OnPostStartMonitoring()
{
    _monitor.MonitoringEnabled = true;
    _monitor.CurrentState = "Monitoring!";

    return RedirectToPage();
}

public IActionResult OnPostStopMonitoring()
{
    _monitor.MonitoringEnabled = false;
    _monitor.CurrentState = "Not monitoring";

    return RedirectToPage();
}

OnPostStartMonitoringTetiklendiğinde izleme etkinleştirilir ve geçerli durum temizlenir. Tetiklendiğinde izleme devre dışı bırakılır ve OnPostStopMonitoring durum, izlemenin meydana olmadığını yansıtacak şekilde ayarlanır.

Kullanıcı arabiriminde düğmeler izlemeyi etkinleştirir ve devre dışı bıraktır.

Pages/Index.cshtml:

<button class="btn btn-success" asp-page-handler="StartMonitoring">
    Start Monitoring
</button>

<button class="btn btn-danger" asp-page-handler="StopMonitoring">
    Stop Monitoring
</button>

Önbelleğe alınmış dosya değişikliklerini izleme

Dosya içeriği kullanılarak bellek içinde önbelleğe IMemoryCache alınabilirsiniz. Bellek içinde önbelleğe alma, Bellek içinde önbelleğe alma konusunda açıklanmıştır. Aşağıda açıklanan uygulama gibi ek adımlar atmadan, kaynak veriler değişirse önbellekten eski (eski) veriler döndürülür.

Örneğin, kayan süre sonu süresi yenilerken önbelleğe alınmış bir kaynak dosyanın durumunu dikkate almama, önbelleğe alınmış eski dosya verilerine yol açıyor. Verilere yapılan her istek, kayan süre sonu süresini yeniler, ancak dosya hiçbir zaman önbelleğe yeniden yüklenmez. Dosyanın önbelleğe alınmış içeriğini kullanan tüm uygulama özellikleri büyük olasılıkla eski içerik almaya tabi olur.

Bir dosya önbelleğe alma senaryosunda değişiklik belirteçlerinin kullanılması önbellekte eski dosya içeriğinin varlığını önler. Örnek uygulama, yaklaşımın bir uygulamasını gösteriyor.

Örnek şunları GetFileContent yapmak için kullanır:

  • Dosya içeriğini iade.
  • Bir dosya kilidinin geçici olarak bir dosyanın okunmaması durumlarını kapsayacak şekilde üstel geri kapatma ile bir yeniden deneme algoritması uygulama.

Utilities/Utilities.cs:

public async static Task<string> GetFileContent(string filePath)
{
    var runCount = 1;

    while(runCount < 4)
    {
        try
        {
            if (File.Exists(filePath))
            {
                using (var fileStreamReader = File.OpenText(filePath))
                {
                    return await fileStreamReader.ReadToEndAsync();
                }
            }
            else 
            {
                throw new FileNotFoundException();
            }
        }
        catch (IOException ex)
        {
            if (runCount == 3 || ex.HResult != -2147024864)
            {
                throw;
            }
            else
            {
                await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, runCount)));
                runCount++;
            }
        }
    }

    return null;
}

Önbelleğe FileService alınmış dosya aramalarını işlemek için oluşturulur. Hizmetin yöntem çağrısı, bellek içinde önbellekten dosya içeriğini alma ve çağırana GetFileContent (Services/FileService.cs) geri çağırmaya çalışır.

Önbelleğe alınmış içerik önbellek anahtarı kullanılarak bulunamazsa aşağıdaki eylemler alınır:

  1. Dosya içeriği kullanılarak elde GetFileContent edilir.
  2. IFileProviders.Watch ile dosya sağlayıcısından bir değişiklik belirteci elde edilir. Dosya değiştirildiğinde belirteci geri çağırma tetiklenir.
  3. Dosya içeriği, kayan süre sonu süresiyle önbelleğe alınmış. Değişiklik belirteci, dosya önbelleğe alınmış sırada değişirse önbellek girdisini çıkararak MemoryCacheEntryExtensions.AddExpirationToken ile ekli olur.

Aşağıdaki örnekte, dosyalar uygulamanın içerik kökünde depolanır. IWebHostEnvironment.ContentRootFileProvider , uygulamanın IFileProvider 'ine işaret etmek için IWebHostEnvironment.ContentRootPath kullanılır. , filePath IFileInfo.PhysicalPath ile elde edilir.

public class FileService
{
    private readonly IMemoryCache _cache;
    private readonly IFileProvider _fileProvider;
    private List<string> _tokens = new List<string>();

    public FileService(IMemoryCache cache, IWebHostEnvironment env)
    {
        _cache = cache;
        _fileProvider = env.ContentRootFileProvider;
    }

    public async Task<string> GetFileContents(string fileName)
    {
        var filePath = _fileProvider.GetFileInfo(fileName).PhysicalPath;
        string fileContent;

        // Try to obtain the file contents from the cache.
        if (_cache.TryGetValue(filePath, out fileContent))
        {
            return fileContent;
        }

        // The cache doesn't have the entry, so obtain the file 
        // contents from the file itself.
        fileContent = await GetFileContent(filePath);

        if (fileContent != null)
        {
            // Obtain a change token from the file provider whose
            // callback is triggered when the file is modified.
            var changeToken = _fileProvider.Watch(fileName);

            // Configure the cache entry options for a five minute
            // sliding expiration and use the change token to
            // expire the file in the cache if the file is
            // modified.
            var cacheEntryOptions = new MemoryCacheEntryOptions()
                .SetSlidingExpiration(TimeSpan.FromMinutes(5))
                .AddExpirationToken(changeToken);

            // Put the file contents into the cache.
            _cache.Set(filePath, fileContent, cacheEntryOptions);

            return fileContent;
        }

        return string.Empty;
    }
}

FileService, bellek önbelleğe alma hizmetiyle birlikte hizmet kapsayıcısı içinde kaydedilir.

Startup.ConfigureServices içinde:

services.AddMemoryCache();
services.AddSingleton<FileService>();

Sayfa modeli, hizmeti kullanarak dosyanın içeriğini yükler.

Dizin sayfasının yönteminde OnGet (Pages/Index.cshtml.cs):

var fileContent = await _fileService.GetFileContents("poem.txt");

CompositeChangeToken sınıfı

Tek bir nesnede IChangeToken bir veya daha fazla örneği temsil eden CompositeChangeToken sınıfını kullanın.

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
        });

HasChanged bileşik belirteç raporlarında true temsil edilen belirteç varsa HasChanged true . ActiveChangeCallbacks bileşik belirteç raporlarında true temsil edilen belirteç varsa ActiveChangeCallbacks true . Birden çok eşzamanlı değişiklik olay oluşursa bileşik değişiklik geri çağırma bir kez çağrılır.

Değişiklik belirteci, durum değişikliklerini izlemek için kullanılan genel amaçlı, düşük düzeyli bir yapı taşıdır.

Örnek kodu görüntüleme veya indirme ( nasılindir)

IChangeToken arabirimi

IChangeToken bir değişikliğin meydana geldiği bildirimleri yalıtır. IChangeToken ad alanı içinde Microsoft.Extensions.Primitives yer almaktadır. Microsoft.AspNetCore.App metapaketini kullanmayan uygulamalar için, Microsoft.Extensions.Primitives NuGet paketi için bir paket başvurusu oluşturun.

IChangeToken iki özelliği vardır:

  • ActiveChangeCallbacks belirteci proaktif olarak geri çağırmaları yükseltin. olarak ActiveChangedCallbacks false ayarlanırsa, hiçbir zaman bir geri çağırma çağrılamaz ve uygulamanın değişiklikleri HasChanged yoklaması gerekir. Herhangi bir değişiklik oluşmazsa veya temel alınan değişiklik dinleyicisi atılabilir veya devre dışı bırakılırsa belirteç hiçbir zaman iptal edilemez.
  • HasChanged bir değişiklik olup ola bir değer alır.

Arabirimi, belirteç değiştirilmeden önce çağrılan bir geri çağırmayı kaydeden IChangeToken RegisterChangeCallback(Action <Object> , Object) yöntemini içerir. HasChanged geri çağırma çağrılmadan önce ayar gerekir.

ChangeToken sınıfı

ChangeToken , bir değişikliğin meydana geldiği bildirimleri yaymada kullanılan statik bir sınıftır. ChangeToken ad alanı içinde Microsoft.Extensions.Primitives yer almaktadır. Microsoft.AspNetCore.App metapaketini kullanmayan uygulamalar için, Microsoft.Extensions.Primitives NuGet paketi için bir paket başvurusu oluşturun.

ChangeToken.OnChange(Func <IChangeToken> , Action) yöntemi, belirteç her Action değiştirilse çağrısı yapmak için bir kaydettirmektedir:

  • Func<IChangeToken> belirteci üretir.
  • Action belirteç değişirken çağrılır.

ChangeToken.OnChange <TState> (Func <IChangeToken> , Action , <TState> TState) aşırı yüklemesi, belirteç tüketicisine geçirilen TState ek bir parametre Action alır.

OnChange bir IDisposable döndürür. çağrısı, Dispose belirteci diğer değişiklikleri dinlemeyi durdurur ve belirteci kaynakları serbest bıraktır.

Verilerde değişiklik belirteçlerinin örnek kullanımları ASP.NET Core

Değişiklik belirteçleri, nesnelerin değişikliklerini izlemek ASP.NET Core önemli bölgelerde kullanılır:

  • Dosyalarda yapılan değişiklikleri izlemek IFileProvider için Watch yönteminin izlemesi IChangeToken için belirtilen dosya veya klasör için bir oluşturur.
  • IChangeToken belirteçler, değişiklik üzerine önbellek çıkarmalarını tetiklemek için önbellek girişlerine eklenebilir.
  • Değişiklikler TOptions için, varsayılan OptionsMonitor<TOptions> uygulamasının bir veya daha fazla örneği kabul eden bir aşırı IOptionsMonitor<TOptions> IOptionsChangeTokenSource<TOptions> yüklemesi vardır. Her örnek, seçenek IChangeToken değişikliklerini izlemek için bir değişiklik bildirimi geri aramasını kaydetmek için bir döndürür.

Yapılandırma değişikliklerini izleme

Varsayılan olarak, ASP.NET Core uygulama yapılandırma ayarlarını yüklemek için JSON yapılandırma dosyalarını ( ,appsettings.Development.jsve appsettings.json üzerinde appsettings.Production.js) kullanır.

Bu dosyalar, üzerinde parametre kabul eden AddJsonFile(IConfigurationBuilder, String, Boolean, Boole) uzantı yöntemi ConfigurationBuilder kullanılarak reloadOnChange yapılandırılır. reloadOnChange , yapılandırmanın dosya değişikliklerinde yeniden yükleniyor olması gerektiğini belirtir. Bu ayar kolaylık WebHost yönteminde CreateDefaultBuilder görünür:

config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, 
          reloadOnChange: true);

Dosya tabanlı yapılandırma ile temsil FileConfigurationSource edildi. FileConfigurationSource , IFileProvider dosyaları izlemek için kullanır.

Varsayılan olarak, IFileMonitor yapılandırma dosyası değişikliklerini izlemek için kullanan PhysicalFileProvider bir tarafından FileSystemWatcher sağlanır.

Örnek uygulama, yapılandırma değişikliklerini izlemek için iki uygulamayı gösterir. Appsettings dosyalardan herhangi biri değişirse, her iki dosya izleme uygulaması da örnek uygulamanın konsola bir ileti yazdığı — özel kodu yürütür.

Bir yapılandırma dosyası, FileSystemWatcher tek bir yapılandırma dosyası değişikliği için birden çok belirteç geri çağırması tetikler. Özel kodun birden çok belirteç geri çağırma tetiklendiğinde yalnızca bir kez çalıştırlendiğinden emin olmak için, örneğin uygulaması dosya karmalarını denetler. Örnek, SHA1 dosya karması kullanır. Üstel geri kapatma ile yeniden deneme uygulanır. Dosyada yeni bir karmanın hesap işlemini geçici olarak engelleyen dosya kilitleme işlemi meydana gelebilir, çünkü yeniden deneme mevcuttur.

Utilities/Utilities.cs:

public static byte[] ComputeHash(string filePath)
{
    var runCount = 1;

    while(runCount < 4)
    {
        try
        {
            if (File.Exists(filePath))
            {
                using (var fs = File.OpenRead(filePath))
                {
                    return System.Security.Cryptography.SHA1
                        .Create().ComputeHash(fs);
                }
            }
            else 
            {
                throw new FileNotFoundException();
            }
        }
        catch (IOException ex)
        {
            if (runCount == 3 || ex.HResult != -2147024864)
            {
                throw;
            }
            else
            {
                Thread.Sleep(TimeSpan.FromSeconds(Math.Pow(2, runCount)));
                runCount++;
            }
        }
    }

    return new byte[20];
}

Basit başlangıç değişiklik belirteci

Yapılandırma yeniden yükleme Action belirteciğine yönelik değişiklik bildirimleri için belirteç tüketici geri çağırmasını kaydetme.

Startup.Configure içinde:

ChangeToken.OnChange(
    () => config.GetReloadToken(),
    (state) => InvokeChanged(state),
    env);

config.GetReloadToken() belirteci sağlar. Geri çağırma InvokeChanged yöntemidir:

private void InvokeChanged(IHostingEnvironment env)
{
    byte[] appsettingsHash = ComputeHash("appSettings.json");
    byte[] appsettingsEnvHash = 
        ComputeHash($"appSettings.{env.EnvironmentName}.json");

    if (!_appsettingsHash.SequenceEqual(appsettingsHash) || 
        !_appsettingsEnvHash.SequenceEqual(appsettingsEnvHash))
    {
        _appsettingsHash = appsettingsHash;
        _appsettingsEnvHash = appsettingsEnvHash;

        WriteConsole("Configuration changed (Simple Startup Change Token)");
    }
}

geri çağırmanın , state izlenirken IHostingEnvironment doğru appsettings yapılandırma dosyasını belirtmek için yararlıdır (örneğin, geliştirme ortamındaappsettings.Development.jsiçin) geçiş yapmak için kullanılır. Yapılandırma dosyası yalnızca bir kez değiştiriken birden çok belirteç geri çağırma nedeniyle deyimin birden çok kez çalıştırılamaması için WriteConsole dosya karmaları kullanılır.

Bu sistem, uygulama çalıştırılmıştır ve kullanıcı tarafından devre dışı bırakılamaz.

Hizmet olarak yapılandırma değişikliklerini izleme

Örnek şunları uygulamaya almaktadır:

  • Temel başlangıç belirteci izleme.
  • Hizmet olarak izleme.
  • İzlemeyi etkinleştirme ve devre dışı bırakma mekanizması.

Örnek bir arabirim IConfigurationMonitor sağlar.

Extensions/ConfigurationMonitor.cs:

public interface IConfigurationMonitor
{
    bool MonitoringEnabled { get; set; }
    string CurrentState { get; set; }
}

Uygulanan sınıfının oluşturucusu, değişiklik ConfigurationMonitor bildirimleri için bir geri çağırmayı kaydettir:

public ConfigurationMonitor(IConfiguration config, IHostingEnvironment env)
{
    _env = env;

    ChangeToken.OnChange<IConfigurationMonitor>(
        () => config.GetReloadToken(),
        InvokeChanged,
        this);
}

public bool MonitoringEnabled { get; set; } = false;
public string CurrentState { get; set; } = "Not monitoring";

config.GetReloadToken() belirteci sağlar. InvokeChanged , geri çağırma yöntemidir. stateBu örnekte, izleme durumuna IConfigurationMonitor erişmek için kullanılan örnek için bir başvuru. İki özellik kullanılır:

  • MonitoringEnabled: Geri çağırmanın özel kodunu çalıştırması gerektiğini gösterir.
  • CurrentState: Kullanıcı arabiriminde kullanmak üzere geçerli izleme durumunu açıklar.

yöntemi, InvokeChanged aşağıdakiler dışında önceki yaklaşıma benzer:

  • değilse kodunu MonitoringEnabled true çalıştırmaz.
  • Çıktıda geçerli state olan çıktıyı WriteConsole oluşturur.
private void InvokeChanged(IConfigurationMonitor state)
{
    if (MonitoringEnabled)
    {
        byte[] appsettingsHash = ComputeHash("appSettings.json");
        byte[] appsettingsEnvHash = 
            ComputeHash($"appSettings.{_env.EnvironmentName}.json");

        if (!_appsettingsHash.SequenceEqual(appsettingsHash) || 
            !_appsettingsEnvHash.SequenceEqual(appsettingsEnvHash))
        {
            string message = $"State updated at {DateTime.Now}";
          

            _appsettingsHash = appsettingsHash;
            _appsettingsEnvHash = appsettingsEnvHash;

            WriteConsole("Configuration changed (ConfigurationMonitor Class) " +
                $"{message}, state:{state.CurrentState}");
        }
    }
}

Bir örnek ConfigurationMonitor içinde hizmet olarak Startup.ConfigureServices kaydedilir:

services.AddSingleton<IConfigurationMonitor, ConfigurationMonitor>();

Dizin sayfası, kullanıcıya yapılandırma izleme üzerinde denetim sunar. örneği IConfigurationMonitor içine IndexModel girildi.

Pages/Index.cshtml.cs:

public IndexModel(
    IConfiguration config, 
    IConfigurationMonitor monitor, 
    FileService fileService)
{
    _config = config;
    _monitor = monitor;
    _fileService = fileService;
}

İzlemeyi etkinleştirmek veya devre dışı bırakmak ve kullanıcı arabirimi geri bildirimi için geçerli durumu ayarlamak için yapılandırma izleyicisi ( _monitor ) kullanılır:

public IActionResult OnPostStartMonitoring()
{
    _monitor.MonitoringEnabled = true;
    _monitor.CurrentState = "Monitoring!";

    return RedirectToPage();
}

public IActionResult OnPostStopMonitoring()
{
    _monitor.MonitoringEnabled = false;
    _monitor.CurrentState = "Not monitoring";

    return RedirectToPage();
}

OnPostStartMonitoringTetiklendiğinde izleme etkinleştirilir ve geçerli durum temizlenir. Tetiklendiğinde izleme devre dışı bırakılır ve OnPostStopMonitoring durum, izlemenin meydana olmadığını yansıtacak şekilde ayarlanır.

Kullanıcı arabiriminde düğmeler izlemeyi etkinleştirir ve devre dışı bıraktır.

Pages/Index.cshtml:

<button class="btn btn-success" asp-page-handler="StartMonitoring">
    Start Monitoring
</button>

<button class="btn btn-danger" asp-page-handler="StopMonitoring">
    Stop Monitoring
</button>

Önbelleğe alınmış dosya değişikliklerini izleme

Dosya içeriği kullanılarak bellek içinde önbelleğe IMemoryCache alınabilirsiniz. Bellek içinde önbelleğe alma, Bellek içinde önbelleğe alma konusunda açıklanmıştır. Aşağıda açıklanan uygulama gibi ek adımlar atmadan, kaynak veriler değişirse önbellekten eski (eski) veriler döndürülür.

Örneğin, kayan süre sonu süresi yenilerken önbelleğe alınmış bir kaynak dosyanın durumunu dikkate almama, önbelleğe alınmış eski dosya verilerine yol açıyor. Verilere yapılan her istek, kayan süre sonu süresini yeniler, ancak dosya hiçbir zaman önbelleğe yeniden yüklenmez. Dosyanın önbelleğe alınmış içeriğini kullanan tüm uygulama özellikleri, büyük olasılıkla eski içerik alınmasına tabidir.

Bir dosya önbelleğe alma senaryosunda değişiklik belirteçlerini kullanmak önbellekte eski dosya içeriğinin varlığını engeller. Örnek uygulama, yaklaşımın bir uygulamasını gösterir.

Örnek şu amaçlarla kullanılır GetFileContent :

  • Dosya içeriğini döndürür.
  • Bir dosya kilidinin geçici olarak bir dosya okumayı engellediği durumları kapsamak için üstel geri ile yeniden deneme algoritması uygulayın.

Yardımcı programlar/yardımcı programlar. cs:

public async static Task<string> GetFileContent(string filePath)
{
    var runCount = 1;

    while(runCount < 4)
    {
        try
        {
            if (File.Exists(filePath))
            {
                using (var fileStreamReader = File.OpenText(filePath))
                {
                    return await fileStreamReader.ReadToEndAsync();
                }
            }
            else 
            {
                throw new FileNotFoundException();
            }
        }
        catch (IOException ex)
        {
            if (runCount == 3 || ex.HResult != -2147024864)
            {
                throw;
            }
            else
            {
                await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, runCount)));
                runCount++;
            }
        }
    }

    return null;
}

FileServiceÖnbelleğe alınmış dosya aramalarını işlemek için oluşturulur. GetFileContentHizmetin Yöntem çağrısı, bellek içi önbellekten dosya içeriğini almaya çalışır ve bunu çağırana (Services/FileService. cs) döndürebilir.

Önbellek anahtarı kullanılarak önbelleğe alınmış içerik bulunamazsa, aşağıdaki eylemler gerçekleştirilir:

  1. Dosya içeriği kullanılarak elde edilir GetFileContent .
  2. Dosya sağlayıcısından ıfileproviders. Watchile bir değişiklik belirteci elde edilir. Dosya değiştirildiğinde belirtecin geri çağırması tetiklenir.
  3. Dosya içeriği bir kayan süre sonu süresiyle önbelleğe alınır. Değişiklik belirteci, önbelleğe alınmış durumdayken dosya değişirse önbellek girdisini çıkarmak için Memorycacheentryextensions. AddExpirationToken ile birlikte eklenir.

Aşağıdaki örnekte, dosyalar uygulamanın içerik kökündesaklanır. Ihostingenvironment. ContentRootFileProvider IFileProvider , uygulamanın üzerine gelindiğinde bir işaret elde etmek için kullanılır ContentRootPath . , filePath Ifıleınfo. PhysicalPathile elde edilir.

public class FileService
{
    private readonly IMemoryCache _cache;
    private readonly IFileProvider _fileProvider;
    private List<string> _tokens = new List<string>();

    public FileService(IMemoryCache cache, IHostingEnvironment env)
    {
        _cache = cache;
        _fileProvider = env.ContentRootFileProvider;
    }

    public async Task<string> GetFileContents(string fileName)
    {
        var filePath = _fileProvider.GetFileInfo(fileName).PhysicalPath;
        string fileContent;

        // Try to obtain the file contents from the cache.
        if (_cache.TryGetValue(filePath, out fileContent))
        {
            return fileContent;
        }

        // The cache doesn't have the entry, so obtain the file 
        // contents from the file itself.
        fileContent = await GetFileContent(filePath);

        if (fileContent != null)
        {
            // Obtain a change token from the file provider whose
            // callback is triggered when the file is modified.
            var changeToken = _fileProvider.Watch(fileName);

            // Configure the cache entry options for a five minute
            // sliding expiration and use the change token to
            // expire the file in the cache if the file is
            // modified.
            var cacheEntryOptions = new MemoryCacheEntryOptions()
                .SetSlidingExpiration(TimeSpan.FromMinutes(5))
                .AddExpirationToken(changeToken);

            // Put the file contents into the cache.
            _cache.Set(filePath, fileContent, cacheEntryOptions);

            return fileContent;
        }

        return string.Empty;
    }
}

, FileService Hizmet kapsayıcısına bellek önbelleği hizmeti ile birlikte kaydedilir.

Startup.ConfigureServices içinde:

services.AddMemoryCache();
services.AddSingleton<FileService>();

Sayfa modeli, hizmeti kullanarak dosyanın içeriğini yükler.

Dizin sayfasının OnGet yönteminde (Pages/Index. cshtml. cs):

var fileContent = await _fileService.GetFileContents("poem.txt");

CompositeChangeToken sınıfı

Tek bir nesnedeki bir veya daha fazla örneği temsil etmek için IChangeToken sınıfını kullanın CompositeChangeToken .

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
        });

HasChanged``trueherhangi bir temsil edilen belirteç varsa bileşik belirteç raporlarında HasChanged true . ActiveChangeCallbacks``trueherhangi bir temsil edilen belirteç varsa bileşik belirteç raporlarında ActiveChangeCallbacks true . Birden çok eşzamanlı değişiklik olayı oluşursa, bileşik değişiklik geri çağırması bir kez çağrılır.

Ek kaynaklar