Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O 📦 Microsoft.Extensions.AsyncState pacote NuGet fornece funcionalidade para armazenar e recuperar objetos dentro do contexto assíncrono atual. Este pacote oferece melhorias de desempenho e usabilidade em relação ao uso AsyncLocal<T> direto, especialmente quando múltiplos objetos precisam de ser partilhados entre operações assíncronas.
Por que usar o AsyncState
Embora .NET forneça AsyncLocal<T> para gerir dados ambientais em contextos assíncronos, usá-lo diretamente pode ter desvantagens:
-
Desempenho: Cada
AsyncLocal<T>instância acrescenta sobrecarga. Quando vários objetos precisam de fluir através de contextos assíncronos, gerir muitasAsyncLocal<T>instâncias pode afetar o desempenho. -
Abstração: O uso direto de
AsyncLocal<T>acopla o seu código a uma implementação específica, dificultando a otimização ou alteração no futuro. - Gestão ao longo da vida: O pacote AsyncState proporciona um melhor controlo sobre a vida útil dos dados ambientes através de APIs explícitas.
O Microsoft.Extensions.AsyncState pacote aborda estas preocupações fornecendo:
- Uma implementação otimizada que reduz o número de
AsyncLocal<T>instâncias necessárias. - Uma abstração limpa para armazenar e recuperar dados ambientes.
- Integração com injeção de dependências para testes e configurações mais simples.
Começar
Para começar com a gestão de estado assíncrona, instale o pacote Microsoft.Extensions.AsyncState NuGet.
dotnet add package Microsoft.Extensions.AsyncState
Para mais informações, consulte dotnet add package ou Manage package dependencies in .NET applications.
Registar serviços de estado assíncrono
Registe os serviços de estado assíncrono no seu contentor de injeção de dependências usando o método de extensão AddAsyncState.
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddAsyncState();
ServiceProvider provider = services.BuildServiceProvider();
Este registo torna as interfaces IAsyncContext<T> e IAsyncState disponíveis para injeção de dependências.
Use IAsyncContext
A IAsyncContext<T> interface fornece métodos para obter e definir valores no contexto assíncrono atual:
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; }
}
O conjunto de valores no contexto flui através de operações assíncronas, tornando-o disponível para todo o código que executa dentro do mesmo contexto assíncrono.
Usar IAsyncState
A interface IAsyncState é a interface de ciclo de vida base que é estendida por IAsyncContext<T>. Fornece Initialize() e Reset() métodos para gerir o ciclo de vida do estado assíncrono. Para acesso tipado a valores de estado assíncronos, use IAsyncContext<T>.
Exemplo prático: correlação de pedidos
Um caso de uso comum para o estado assíncrono é manter a informação de correlação através de um pedido 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; }
}
Neste exemplo, o ID de correlação é definido uma vez no início do processamento do pedido e está automaticamente disponível em todas as operações assíncronas subsequentes, sem necessidade de o passar como parâmetro.
Integração ASP.NET Core
Nas aplicações ASP.NET Core, pode usar o estado assíncrono para transferir informação específica do pedido através da sua aplicação:
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; }
}
Melhores práticas
Ao usar o estado assíncrono, considere as seguintes melhores práticas:
- Limitar o tamanho do estado: Mantenha os objetos de estado assíncrono pequenos para reduzir a sobrecarga de memória e manter o desempenho.
- Inicializar o estado cedo: Defina os valores do estado assíncrono o mais cedo possível para garantir que estão disponíveis para todas as operações assíncronas subsequentes.
- Estado de limpeza: Reiniciar ou limpar o estado assíncrono quando já não for necessário para evitar fugas de memória em aplicações de longa duração.
-
Use interfaces apropriadas: Use
IAsyncContext<T>para obter e definir valores tipados dentro do contexto assíncrono atual. UsaIAsyncStatequando precisares de gerir diretamente o ciclo de inicialização e reset. - segurança de tipos: Criar tipos de contexto específicos em vez de usar dicionários genéricos para manter a segurança dos tipos e melhorar a clarity do código.