Asenkron durum yönetimi

📦 Microsoft.Extensions.AsyncState NuGet paketi, geçerli zaman uyumsuz bağlam içindeki nesneleri depolamak ve almak için işlevsellik sağlar. Bu paket, özellikle birden çok nesnenin zaman uyumsuz işlemler arasında paylaşılması gerektiğinde doğrudan kullanım AsyncLocal<T> üzerinde performans ve kullanılabilirlik iyileştirmeleri sunar.

AsyncState neden kullanılır?

.NET zaman uyumsuz bağlamlarda ortam verilerini yönetmek için AsyncLocal<T> sağlarken, doğrudan kullanmanın dezavantajları olabilir:

  • Performans: Her AsyncLocal<T> örnek ek yük ekler. Birden çok nesnenin zaman uyumsuz bağlamlarda akması gerektiğinde, birden fazla AsyncLocal<T> örneğini yönetmek performansı etkileyebilir.
  • Soyutlama: Doğrudan kullanım AsyncLocal<T> , kodunuzu belirli bir uygulamayla bağlayarak gelecekte iyileştirmeyi veya değiştirmeyi zorlaştırır.
  • Yaşam süresi yönetimi: AsyncState paketi, açık API'ler aracılığıyla ortam verilerinin ömrü üzerinde daha iyi denetim sağlar.

Bu paket, şunları sağlayarak Microsoft.Extensions.AsyncState bu endişeleri giderir:

  • Gereken örnek sayısını AsyncLocal<T> azaltan iyileştirilmiş bir uygulama.
  • Ortam verilerini depolamak ve almak için temiz bir soyutlama.
  • Daha kolay test ve yapılandırma için bağımlılık enjeksiyonu ile tümleştirme.

Başlayın

Zaman uyumsuz durum yönetimine başlamak için Microsoft.Extensions.AsyncState NuGet paketini yükleyin.

dotnet add package Microsoft.Extensions.AsyncState

Daha fazla bilgi için bkz. dotnet add package veya .NET uygulamalarında paket bağımlılıklarını yönetme.

Zaman uyumsuz durum hizmetlerini kaydet

Uzantı yöntemini kullanarak AddAsyncState zaman uyumsuz durum hizmetlerini bağımlılık ekleme kapsayıcınıza kaydedin:

using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();

services.AddAsyncState();

ServiceProvider provider = services.BuildServiceProvider();

Bu kayıt IAsyncContext<T> ve IAsyncState arabirimlerini bağımlılık ekleme için kullanılabilir hale getirir.

IAsyncContext kullanma

Arabirim, geçerli eş zamansız bağlamdaki değerleri almak ve ayarlamak için IAsyncContext<T> yöntemler sağlar.

var context = provider.GetRequiredService<IAsyncContext<UserContext>>();

// Set a value in the async context
var userContext = new UserContext { UserId = "12345", UserName = "Alice" };
context.Set(userContext);

// Retrieve the value
if (context.TryGet(out var retrievedContext))
{
    Console.WriteLine($"User: {retrievedContext.UserName}");
}
public record class UserContext
{
    public required string UserId { get; set; }
    public required string UserName { get; set; }
}

Bağlamda ayarlanan değer, zaman uyumsuz işlemler sırasında akarak, aynı zaman uyumsuz bağlamda yürütülen tüm kodlar için erişilebilir hale gelir.

IAsyncState kullanımı

Arayüz IAsyncState, IAsyncContext<T> tarafından genişletilen temel yaşam döngüsü arayüzüdür. Initialize() ve Reset() yöntemleri, zaman uyumsuz durum yaşam döngüsünü yönetmek için sağlar. Zaman uyumsuz durum değerlerine erişim için bunun yerine IAsyncContext<T> kullanın.

Pratik örnek: bağıntı isteme

Asenkron durum için yaygın bir kullanım örneği, bir HTTP isteği süresince ilişkilendirme bilgilerini korumaktır.

public class RequestProcessor(IAsyncContext<CorrelationContext> asyncContext)
{

    public async Task ProcessRequestAsync(string correlationId)
    {
        // Set correlation context at the beginning of request processing
        asyncContext.Set(new CorrelationContext { CorrelationId = correlationId });

        // The correlation ID flows through all async operations
        await Step1Async();
        await Step2Async();
    }

    private async Task Step1Async()
    {
        await Task.Yield();
        
        if (asyncContext.TryGet(out var context))
        {
            Console.WriteLine($"Step 1 - Correlation ID: {context.CorrelationId}");
        }
    }

    private async Task Step2Async()
    {
        await Task.Yield();
        
        if (asyncContext.TryGet(out var context))
        {
            Console.WriteLine($"Step 2 - Correlation ID: {context.CorrelationId}");
        }
    }
}
public class CorrelationContext
{
    public required string CorrelationId { get; set; }
}

Bu örnekte, bağıntı kimliği istek işlemenin başlangıcında bir kez ayarlanır ve parametre olarak geçirilmesi gerekmeden sonraki tüm zaman uyumsuz işlemlerde otomatik olarak kullanılabilir.

ASP.NET Core tümleştirmesi

ASP.NET Core uygulamalarında, uygulamanız aracılığıyla isteğe özel bilgileri uygun şekilde aktarmak için asenkron durumu kullanabilirsiniz.

public class RequestHandler(IAsyncContext<RequestMetadata> asyncContext)
{

    public async Task<object> GetDataAsync()
    {
        await Task.Yield();
        
        if (asyncContext.TryGet(out var metadata))
        {
            var duration = DateTimeOffset.UtcNow - metadata.StartTime;
            return new
            {
                RequestId = metadata.RequestId,
                RequestPath = metadata.RequestPath,
                Duration = duration.TotalMilliseconds
            };
        }

        return new { Error = "No request metadata available" };
    }
}
public record class RequestMetadata
{
    public required string RequestId { get; set; }
    public required string RequestPath { get; set; }
    public DateTimeOffset StartTime { get; set; }
}

En iyi yöntemler

Zaman uyumsuz durumu kullanırken aşağıdaki en iyi yöntemleri göz önünde bulundurun:

  • Durum boyutunu sınırla: Bellek yükünü azaltmak ve performansı korumak için zaman uyumsuz durum nesnelerini küçük tutun.
  • Durumu erken başlat: Tüm aşağı yönde gerçekleşen zaman uyumsuz işlemler için kullanılabilir olmalarını sağlamak amacıyla zaman uyumsuz durum değerlerini olabildiğince erken ayarlayın.
  • Temizleme durumu: Uzun süre çalışan uygulamalarda bellek sızıntılarını önlemek için artık gerekli olmadığında zaman uyumsuz durumu sıfırlayın veya temizleyin.
  • Uygun arabirimleri kullanın: Geçerli zaman uyumsuz bağlam içinde yazılan değerleri almak ve ayarlamak için IAsyncContext<T> kullanın. Başlatmayı doğrudan yönetmeniz ve yaşam döngüsünü sıfırlamanız gerektiğinde kullanın IAsyncState .
  • Type safety: Tür güvenliğini korumak ve kod netliğini geliştirmek için genel sözlükler kullanmak yerine belirli bağlam türleri oluşturun.

Ayrıca bakınız