Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il 📦 Microsoft.Extensions.AsyncState pacchetto NuGet offre funzionalità per archiviare e recuperare oggetti all'interno del contesto asincrono corrente. Questo pacchetto offre miglioramenti delle prestazioni e dell'usabilità rispetto all'uso AsyncLocal<T> diretto, in particolare quando più oggetti devono essere condivisi tra operazioni asincrone.
Perché usare AsyncState
Anche se .NET fornisce AsyncLocal<T> per la gestione dei dati di ambiente in contesti asincroni, l'uso diretto può avere svantaggi:
-
Le prestazioni: ogni
AsyncLocal<T>istanza aggiunge overhead. Quando più oggetti devono passare attraverso contesti asincroni, la gestione di molteAsyncLocal<T>istanze può influire sulle prestazioni. -
Astrazione: l'uso diretto di
AsyncLocal<T>associa il codice a un'implementazione specifica, rendendo più difficile ottimizzare o modificare in futuro. - Gestione della durata: il pacchetto AsyncState offre un migliore controllo sulla durata dei dati di ambiente tramite API esplicite.
Il Microsoft.Extensions.AsyncState pacchetto risolve questi problemi fornendo:
- Implementazione ottimizzata che riduce il numero di
AsyncLocal<T>istanze necessarie. - Astrazione pulita per l'archiviazione e il recupero dei dati di ambiente.
- Integrazione con l'iniezione delle dipendenze per semplificare test e configurazione.
Inizia
Per iniziare con la gestione asincrona dello stato, installare il pacchetto NuGet Microsoft.Extensions.AsyncState.
dotnet add package Microsoft.Extensions.AsyncState
Per altre informazioni, vedere dotnet add package or Gestire le dipendenze dei pacchetti nelle applicazioni .NET.
Registrare i servizi di stato asincroni
Registrare i servizi di stato asincroni con il contenitore per l'iniezione delle dipendenze utilizzando il metodo di estensione AddAsyncState.
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddAsyncState();
ServiceProvider provider = services.BuildServiceProvider();
Questa registrazione rende disponibili le interfacce IAsyncContext<T> e IAsyncState per l'iniezione delle dipendenze.
Usare IAsyncContext
L'interfaccia IAsyncContext<T> fornisce metodi per ottenere e impostare i valori nel contesto asincrono corrente:
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; }
}
Il valore impostato nel contesto scorre attraverso operazioni asincrone, rendendolo disponibile per tutto il codice in esecuzione nello stesso contesto asincrono.
Usare IAsyncState
L'interfaccia IAsyncState è l'interfaccia del ciclo di vita di base che IAsyncContext<T> estende. Fornisce i metodi Initialize() e Reset() per la gestione del ciclo di vita dello stato asincrono. Per gli accessi tipizzati ai valori di stato asincrono, usare invece IAsyncContext<T>.
Esempio pratico: Richiedere la correlazione
Un caso d'uso comune per lo stato asincrono consiste nel mantenere le informazioni di correlazione in una richiesta 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; }
}
In questo esempio, l'ID di correlazione viene impostato una sola volta all'inizio dell'elaborazione della richiesta ed è automaticamente disponibile in tutte le operazioni asincrone successive senza che sia necessario passarlo come parametro.
integrazione di ASP.NET Core
Nelle applicazioni ASP.NET Core è possibile usare lo stato asincrono per eseguire il flusso di informazioni specifiche della richiesta tramite l'applicazione:
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; }
}
Procedure consigliate
Quando si usa lo stato asincrono, considerare le procedure consigliate seguenti:
- Limitare le dimensioni dello stato: mantenere gli oggetti di stato asincroni di piccole dimensioni per ridurre il sovraccarico della memoria e mantenere le prestazioni.
- Inizializzare lo stato in anticipo: impostare i valori dello stato asincrono il prima possibile per assicurarsi che siano disponibili per tutte le operazioni asincrone downstream.
- Pulizia dello stato: reimpostare o cancellare lo stato asincrono quando non è più necessario per evitare perdite di memoria nelle applicazioni a esecuzione prolungata.
-
Usare le interfacce appropriate: usare
IAsyncContext<T>per ottenere e impostare valori tipizzati all'interno del contesto asincrono corrente. UsareIAsyncStatequando è necessario gestire direttamente l'inizializzazione e il ciclo di vita di reimpostazione. - Type safety: creare tipi di contesto specifici anziché usare dizionari generici per mantenere la sicurezza dei tipi e migliorare il clarity del codice.