Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
📦 Microsoft.Extensions.AsyncState Pakiet NuGet udostępnia funkcje przechowywania i pobierania obiektów w bieżącym kontekście asynchronicznym. Ten pakiet oferuje ulepszenia wydajności i użyteczności w przypadku bezpośredniego używania AsyncLocal<T> , szczególnie w przypadku konieczności współużytkowania wielu obiektów w operacjach asynchronicznych.
Dlaczego warto używać klasy AsyncState
Chociaż .NET zapewnia AsyncLocal<T> do zarządzania danymi otoczenia w kontekstach asynchronicznych, użycie ich bezpośrednio może mieć wady:
-
Wydajność: każde
AsyncLocal<T>wystąpienie dodaje obciążenie. Jeśli wiele obiektów musi przepływać przez konteksty asynchroniczne, zarządzanie wielomaAsyncLocal<T>wystąpieniami może mieć wpływ na wydajność. - pl-PL: Abstrakcja: bezpośrednie użycie
AsyncLocal<T>wiąże twój kod z konkretną implementacją, co utrudnia optymalizację lub zmianę w przyszłości. - Zarządzanie okresem istnienia: pakiet AsyncState zapewnia lepszą kontrolę nad okresem istnienia danych otoczenia za pośrednictwem jawnych interfejsów API.
Pakiet Microsoft.Extensions.AsyncState rozwiązuje te problemy, udostępniając następujące kwestie:
- Zoptymalizowana implementacja, która zmniejsza liczbę potrzebnych
AsyncLocal<T>wystąpień. - Czysta abstrakcja do przechowywania i pobierania danych otoczenia.
- Integracja z iniekcją zależności w celu ułatwienia testowania i konfigurowania.
Zacznij
Aby zacząć z zarządzaniem stanem asynchronicznym, zainstaluj pakiet NuGet Microsoft.Extensions.AsyncState.
- interfejs wiersza polecenia .NET
- PackageReference
dotnet add package Microsoft.Extensions.AsyncState
Aby uzyskać więcej informacji, zobacz dotnet add package lub Zarządzanie zależnościami pakietów w aplikacjach .NET.
Rejestrowanie usług stanu asynchronicznego
Zarejestruj usługi stanu asynchronicznego w kontenerze wstrzykiwania zależności przy użyciu metody rozszerzenia AddAsyncState:
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddAsyncState();
ServiceProvider provider = services.BuildServiceProvider();
Ta rejestracja udostępnia interfejsy IAsyncContext<T> i IAsyncState do wstrzykiwania zależności.
Korzystanie z elementu IAsyncContext
Interfejs IAsyncContext<T> udostępnia metody do pobierania i ustawiania wartości w bieżącym kontekście asynchronicznym.
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; }
}
Wartość ustawiona w kontekście przepływa przez operacje asynchroniczne, udostępniając go wszystkim kodom wykonywanym w tym samym kontekście asynchronicznym.
Użycie IAsyncState
Interfejs IAsyncState to podstawowy interfejs cyklu życia, który IAsyncContext<T> rozszerza.
Initialize() i Reset() metody zapewnia do zarządzania cyklem życia stanu asynchronicznego. Aby uzyskać typizowany dostęp do wartości stanu asynchronicznego, użyj IAsyncContext<T>.
Praktyczny przykład: korelacja żądań
Typowy przypadek użycia stanu asynchronicznego to utrzymywanie informacji o korelacji w obrębie żądania HTTP.
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; }
}
W tym przykładzie identyfikator korelacji jest ustawiany raz na początku przetwarzania żądań i jest automatycznie dostępny we wszystkich kolejnych operacjach asynchronicznych bez konieczności przekazywania go jako parametru.
integracja ASP.NET Core
W aplikacjach ASP.NET Core możesz użyć stanu asynchronicznego do przepływu informacji specyficznych dla żądania za pośrednictwem aplikacji:
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; }
}
Najlepsze rozwiązania
W przypadku korzystania ze stanu asynchronicznego należy wziąć pod uwagę następujące najlepsze rozwiązania:
- Rozmiar stanu limitu: zachowaj małe obiekty stanu asynchronicznego, aby zmniejszyć obciążenie pamięci i utrzymać wydajność.
- Wczesne inicjowanie stanu: Ustaw wartości stanu asynchronicznego tak szybko, jak to możliwe, aby upewnić się, że są dostępne dla wszystkich późniejszych operacji asynchronicznych.
- Stan czyszczenia: zresetuj lub wyczyść stan asynchroniczny, gdy nie jest już potrzebny, aby uniknąć przecieków pamięci w długotrwałych aplikacjach.
-
Użyj odpowiednich interfejsów: użyj
IAsyncContext<T>, aby pobrać i ustawić typizowane wartości w bieżącym kontekście asynchronicznym. UżyjIAsyncState, gdy potrzebujesz bezpośrednio zarządzać cyklem życia inicjalizacji i resetowania. - Type safety: Tworzenie określonych typów kontekstowych zamiast używania słowników ogólnych w celu zachowania bezpieczeństwa typów i ulepszania clarity kodu.