Aracılığıyla paylaş


ASP.NET Core'da değişiklik belirteçleriyle değişiklikleri algılama

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.

Uyarı

ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.

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 (indirme)

IChangeToken arabirimi

IChangeToken bir değişikliğin oluştuğuna ilişkin bildirimleri yayılım. IChangeToken ad alanında Microsoft.Extensions.Primitives bulunur. Microsoft.Extensions.Primitives NuGet paketi, ASP.NET Core uygulamalarına örtük olarak sağlanır.

IChangeToken iki özelliğe sahiptir:

  • ActiveChangeCallbacks belirtecin geri çağırmaları proaktif olarak tetiklediğini gösterir. olarak ayarlanırsa ActiveChangedCallbacks false, geri arama hiçbir zaman çağrılmaz ve uygulamanın değişiklikleri yoklaması HasChanged gerekir. Ayrıca hiçbir değişiklik yapılmazsa veya temel alınan değişiklik dinleyicisi atılırsa veya devre dışı bırakılırsa belirtecin hiçbir zaman iptal edilmeyeceği de mümkündür.
  • HasChanged bir değişiklik olup olmadığını belirten bir değer alır.

Arabirim, IChangeToken belirteç değiştiğinde çağrılan bir geri çağırmayı kaydeden RegisterChangeCallback(Eylem<Nesnesi>, Nesne) yöntemini içerir. HasChanged geri çağırma çağrılmadan önce ayarlanmalıdır.

ChangeToken sınıfı

ChangeToken , bir değişikliğin oluştuğuna ilişkin bildirimleri yaymak için kullanılan statik bir sınıftır. ChangeToken ad alanında Microsoft.Extensions.Primitives bulunur. Microsoft.Extensions.Primitives NuGet paketi, ASP.NET Core uygulamalarına örtük olarak sağlanır.

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

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

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

OnChange döndürür IDisposable. Çağrısı Dispose , belirtecin daha fazla değişiklik dinlemesini durdurur ve belirtecin kaynaklarını serbest bırakır.

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

Değişiklik belirteçleri, nesnelerdeki değişiklikleri izlemek için ASP.NET Core'un öne çıkan alanlarında kullanılır:

  • Dosyalarda yapılan değişiklikleri izlemek için yöntemi, IFileProviderWatch izlenecek belirtilen dosya veya klasör için bir IChangeToken oluşturur.
  • IChangeToken belirteçler önbellek girişlerine eklenerek değişiklikte önbellek çıkarmaları tetiklenebilir.
  • Değişiklikler için TOptions , varsayılan OptionsMonitor<TOptions> uygulaması IOptionsMonitor<TOptions> bir veya daha fazla IOptionsChangeTokenSource<TOptions> örneği kabul eden bir aşırı yüklemeye sahiptir. Her örnek, değişiklik değişikliklerini izlemek için bir değişiklik bildirimi geri çağırması kaydetmek için döndürür IChangeToken .

Yapılandırma değişikliklerini izleme

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

Bu dosyalar, parametresini reloadOnChange kabul eden AddJsonFile(IConfigurationBuilder, String, Boole, Boolean) uzantısı yöntemi ConfigurationBuilder kullanılarak yapılandırılır. reloadOnChange , yapılandırmanın dosya değişikliklerine yeniden yüklenmesi gerekip gerekmediğini gösterir. Bu ayar, kolaylık yönteminde Host CreateDefaultBuildergö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 FileConfigurationSourcetemsil edilir. FileConfigurationSource dosyaları izlemek için kullanır IFileProvider .

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

Örnek uygulama, yapılandırma değişikliklerini izlemek için iki uygulama gösterir. Dosyalardan herhangi biri appsettings değişirse, her iki dosya izleme uygulaması da özel kod yürütür; örnek uygulama konsola bir ileti yazar.

Bir yapılandırma dosyası, FileSystemWatcher tek bir yapılandırma dosyası değişikliği için birden çok belirteç geri çağırma tetikleyebilir. Özel kodun birden çok belirteç geri çağırma tetiklendiğinde yalnızca bir kez çalıştırıldığından emin olmak için, örneğin uygulaması dosya karmalarını denetler. Örnek, SHA1 dosya karması kullanır. Üstel geri alma ile yeniden deneme uygulanır.

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

            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 belirtecine değişiklik bildirimleri için bir belirteç tüketici Action geri çağırması kaydedin.

Startup.Configure içinde:

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

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

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

state Geri çağırmanın değeri, izlenecek doğru appsettings yapılandırma dosyasını belirtmek için (örneğin, appsettings.Development.json Geliştirme ortamındayken) için yararlı olan değerini geçirmek IWebHostEnvironmentiçin kullanılır. Dosya karmaları, yapılandırma dosyası yalnızca bir kez değiştiğinde birden çok belirteç geri çağırması nedeniyle deyimin birden çok kez çalışmasını önlemek WriteConsole için kullanılır.

Uygulama çalıştığı ve kullanıcı tarafından devre dışı bırakılabildiği sürece bu sistem çalışır.

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

Örnek aşağıdakileri uygular:

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

Örnek bir IConfigurationMonitor arabirim oluşturur.

Extensions/ConfigurationMonitor.cs:

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

Uygulanan sınıfının ConfigurationMonitoroluşturucu, değişiklik bildirimleri için bir geri çağırma kaydeder:

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. state Bu örnekte, izleme durumuna erişmek için IConfigurationMonitor kullanılan örneğe bir başvurudur. İki özellik kullanılır:

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

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

  • olmadığı sürece MonitoringEnabled truekodunu çalıştırmaz.
  • Çıkışında geçerli state çıkışı alır WriteConsole .
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 bir hizmet Startup.ConfigureServicesolarak kaydedilir:

services.AddSingleton<IConfigurationMonitor, ConfigurationMonitor>();

Dizin sayfası, yapılandırma izleme üzerinde kullanıcı denetimi sunar. örneği IConfigurationMonitor içine IndexModeleklenir.

Pages/Index.cshtml.cs:

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

Yapılandırma izleyicisi (_monitor), izlemeyi etkinleştirmek veya devre dışı bırakmak ve kullanıcı arabirimi geri bildirimi için geçerli durumu ayarlamak için 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();
}

Tetiklendiğinde OnPostStartMonitoring izleme etkinleştirilir ve geçerli durum temizlenir. Tetiklendiğinde OnPostStopMonitoring izleme devre dışı bırakılır ve durum izlemenin gerçekleşmediğini yansıtacak şekilde ayarlanır.

Kullanıcı arabirimindeki düğmeler izlemeyi etkinleştirir ve devre dışı bırakı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ınan dosya değişikliklerini izleme

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

Örneğin, kayan süre sonu süresi yenilenirken önbelleğe alınmış bir kaynak dosyanın durumunu dikkate almamak, önbelleğe alınmış eski dosya verilerine yol açar. Veriler için 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 eski içerik alma olasılığına tabidir.

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

Örnek, aşağıdakileri yapmak için kullanır GetFileContent :

  • Dosya içeriğini döndür.
  • Dosya erişim sorununun dosyanın içeriğini okumayı geçici olarak geciktirdiği durumları karşılamak için üstel geri alma ile yeniden deneme algoritması uygulayın.

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

            Thread.Sleep(TimeSpan.FromSeconds(Math.Pow(2, runCount)));
            runCount++;
        }
    }

    return null;
}

FileService önbelleğe alınmış dosya aramalarını işlemek için oluşturulur. Hizmetin GetFileContent yöntem çağrısı, bellek içi önbellekten dosya içeriği edinmeye ve çağırana (Services/FileService.cs ) döndürmeye çalışır.

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

  1. Dosya içeriği kullanılarak GetFileContentelde edilir.
  2. IFileProviders.Watch ile dosya sağlayıcısından bir değişiklik belirteci alınır. Dosya değiştirildiğinde belirtecin geri çağırması tetikleniyor.
  3. Dosya içeriği kayan süre sonu süresiyle önbelleğe alınır. Değişiklik belirteci MemoryCacheEntryExtensions.AddExpirationToken ile eklendiğinde, dosya önbelleğe alınırken değişirse önbellek girdisi çıkarılır.

Aşağıdaki örnekte dosyalar uygulamanın içerik kökünde depolanır. IWebHostEnvironment.ContentRootFileProvider, uygulamanın IWebHostEnvironment.ContentRootPathöğesine işaret eden bir IFileProvider elde etmek için 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ına 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 nesnede bir veya daha fazla IChangeToken örneği temsil etmek için sınıfını CompositeChangeToken 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 bir belirteç HasChanged varsa true. ActiveChangeCallbacks bileşik belirteç raporlarında true temsil edilen bir belirteç ActiveChangeCallbacks varsa true. Birden çok eşzamanlı değişiklik olayı oluşursa, bileşik değişiklik geri çağrısı 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 (indirme)

IChangeToken arabirimi

IChangeToken bir değişikliğin oluştuğuna ilişkin bildirimleri yayılım. IChangeToken ad alanında Microsoft.Extensions.Primitives bulunur. Microsoft.AspNetCore.App meta paketini kullanmayan uygulamalar için Microsoft.Extensions.Primitives NuGet paketi için bir paket başvurusu oluşturun.

IChangeToken iki özelliğe sahiptir:

  • ActiveChangeCallbacks belirtecin geri çağırmaları proaktif olarak tetiklediğini gösterir. olarak ayarlanırsa ActiveChangedCallbacks false, geri arama hiçbir zaman çağrılmaz ve uygulamanın değişiklikleri yoklaması HasChanged gerekir. Ayrıca hiçbir değişiklik yapılmazsa veya temel alınan değişiklik dinleyicisi atılırsa veya devre dışı bırakılırsa belirtecin hiçbir zaman iptal edilmeyeceği de mümkündür.
  • HasChanged bir değişiklik olup olmadığını belirten bir değer alır.

Arabirim, IChangeToken belirteç değiştiğinde çağrılan bir geri çağırmayı kaydeden RegisterChangeCallback(Eylem<Nesnesi>, Nesne) yöntemini içerir. HasChanged geri çağırma çağrılmadan önce ayarlanmalıdır.

ChangeToken sınıfı

ChangeToken , bir değişikliğin oluştuğuna ilişkin bildirimleri yaymak için kullanılan statik bir sınıftır. ChangeToken ad alanında Microsoft.Extensions.Primitives bulunur. Microsoft.AspNetCore.App meta paketini 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 değiştiğinde çağrısı için bir Action kaydeder:

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

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

OnChange döndürür IDisposable. Çağrısı Dispose , belirtecin daha fazla değişiklik dinlemesini durdurur ve belirtecin kaynaklarını serbest bırakır.

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

Değişiklik belirteçleri, nesnelerdeki değişiklikleri izlemek için ASP.NET Core'un öne çıkan alanlarında kullanılır:

  • Dosyalarda yapılan değişiklikleri izlemek için yöntemi, IFileProviderWatch izlenecek belirtilen dosya veya klasör için bir IChangeToken oluşturur.
  • IChangeToken belirteçler önbellek girişlerine eklenerek değişiklikte önbellek çıkarmaları tetiklenebilir.
  • Değişiklikler için TOptions , varsayılan OptionsMonitor<TOptions> uygulaması IOptionsMonitor<TOptions> bir veya daha fazla IOptionsChangeTokenSource<TOptions> örneği kabul eden bir aşırı yüklemeye sahiptir. Her örnek, değişiklik değişikliklerini izlemek için bir değişiklik bildirimi geri çağırması kaydetmek için döndürür IChangeToken .

Yapılandırma değişikliklerini izleme

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

Bu dosyalar, parametresini reloadOnChange kabul eden AddJsonFile(IConfigurationBuilder, String, Boole, Boolean) uzantısı yöntemi ConfigurationBuilder kullanılarak yapılandırılır. reloadOnChange , yapılandırmanın dosya değişikliklerine yeniden yüklenmesi gerekip gerekmediğini gösterir. Bu ayar, kolaylık yönteminde WebHost CreateDefaultBuildergö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 FileConfigurationSourcetemsil edilir. FileConfigurationSource dosyaları izlemek için kullanır IFileProvider .

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

Örnek uygulama, yapılandırma değişikliklerini izlemek için iki uygulama gösterir. Dosyalardan herhangi biri appsettings değişirse, her iki dosya izleme uygulaması da özel kod yürütür; örnek uygulama konsola bir ileti yazar.

Bir yapılandırma dosyası, FileSystemWatcher tek bir yapılandırma dosyası değişikliği için birden çok belirteç geri çağırma tetikleyebilir. Özel kodun birden çok belirteç geri çağırma tetiklendiğinde yalnızca bir kez çalıştırıldığından emin olmak için, örneğin uygulaması dosya karmalarını denetler. Örnek, SHA1 dosya karması kullanır. Üstel geri alma ile yeniden deneme uygulanır.

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

            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 belirtecine değişiklik bildirimleri için bir belirteç tüketici Action geri çağırması kaydedin.

Startup.Configure içinde:

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

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

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

state Geri çağırmanın değeri, izlenecek doğru appsettings yapılandırma dosyasını belirtmek için (örneğin, appsettings.Development.json Geliştirme ortamındayken) için yararlı olan değerini geçirmek IHostingEnvironmentiçin kullanılır. Dosya karmaları, yapılandırma dosyası yalnızca bir kez değiştiğinde birden çok belirteç geri çağırması nedeniyle deyimin birden çok kez çalışmasını önlemek WriteConsole için kullanılır.

Uygulama çalıştığı ve kullanıcı tarafından devre dışı bırakılabildiği sürece bu sistem çalışır.

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

Örnek aşağıdakileri uygular:

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

Örnek bir IConfigurationMonitor arabirim oluşturur.

Extensions/ConfigurationMonitor.cs:

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

Uygulanan sınıfının ConfigurationMonitoroluşturucu, değişiklik bildirimleri için bir geri çağırma kaydeder:

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. state Bu örnekte, izleme durumuna erişmek için IConfigurationMonitor kullanılan örneğe bir başvurudur. İki özellik kullanılır:

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

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

  • olmadığı sürece MonitoringEnabled truekodunu çalıştırmaz.
  • Çıkışında geçerli state çıkışı alır WriteConsole .
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 bir hizmet Startup.ConfigureServicesolarak kaydedilir:

services.AddSingleton<IConfigurationMonitor, ConfigurationMonitor>();

Dizin sayfası, yapılandırma izleme üzerinde kullanıcı denetimi sunar. örneği IConfigurationMonitor içine IndexModeleklenir.

Pages/Index.cshtml.cs:

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

Yapılandırma izleyicisi (_monitor), izlemeyi etkinleştirmek veya devre dışı bırakmak ve kullanıcı arabirimi geri bildirimi için geçerli durumu ayarlamak için 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();
}

Tetiklendiğinde OnPostStartMonitoring izleme etkinleştirilir ve geçerli durum temizlenir. Tetiklendiğinde OnPostStopMonitoring izleme devre dışı bırakılır ve durum izlemenin gerçekleşmediğini yansıtacak şekilde ayarlanır.

Kullanıcı arabirimindeki düğmeler izlemeyi etkinleştirir ve devre dışı bırakı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ınan dosya değişikliklerini izleme

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

Örneğin, kayan süre sonu süresi yenilenirken önbelleğe alınmış bir kaynak dosyanın durumunu dikkate almamak, önbelleğe alınmış eski dosya verilerine yol açar. Veriler için 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 eski içerik alma olasılığına tabidir.

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

Örnek, aşağıdakileri yapmak için kullanır GetFileContent :

  • Dosya içeriğini döndür.
  • Dosya erişim sorununun dosyanın içeriğini okumayı geçici olarak geciktirdiği durumları karşılamak için üstel geri alma ile yeniden deneme algoritması uygulayın.

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

FileService önbelleğe alınmış dosya aramalarını işlemek için oluşturulur. Hizmetin GetFileContent yöntem çağrısı, bellek içi önbellekten dosya içeriği edinmeye ve çağırana (Services/FileService.cs ) döndürmeye çalışır.

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

  1. Dosya içeriği kullanılarak GetFileContentelde edilir.
  2. IFileProviders.Watch ile dosya sağlayıcısından bir değişiklik belirteci alınır. Dosya değiştirildiğinde belirtecin geri çağırması tetikleniyor.
  3. Dosya içeriği kayan süre sonu süresiyle önbelleğe alınır. Değişiklik belirteci MemoryCacheEntryExtensions.AddExpirationToken ile eklendiğinde, dosya önbelleğe alınırken değişirse önbellek girdisi çıkarılır.

Aşağıdaki örnekte dosyalar uygulamanın içerik kökünde depolanır. IHostingEnvironment.ContentRootFileProvider, uygulamanın ContentRootPathöğesine işaret etmek için IFileProvider 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, 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, bellek önbelleğe alma hizmetiyle birlikte hizmet kapsayıcısına 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 nesnede bir veya daha fazla IChangeToken örneği temsil etmek için sınıfını CompositeChangeToken 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 bir belirteç HasChanged varsa true. ActiveChangeCallbacks bileşik belirteç raporlarında true temsil edilen bir belirteç ActiveChangeCallbacks varsa true. Birden çok eşzamanlı değişiklik olayı oluşursa, bileşik değişiklik geri çağrısı bir kez çağrılır.

Ek kaynaklar