Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você 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. Esse pacote oferece melhorias de desempenho e usabilidade em comparação com o uso direto de AsyncLocal<T>, especialmente quando vários objetos precisam ser compartilhados em operações assíncronas.
Por que usar AsyncState
Embora .NET forneça AsyncLocal<T> para gerenciar dados ambientes em contextos assíncronos, usá-los diretamente pode ter desvantagens:
-
Desempenho: cada
AsyncLocal<T>instância adiciona sobrecarga. Quando vários objetos precisam fluir por contextos assíncronos, o gerenciamento de muitasAsyncLocal<T>instâncias pode afetar o desempenho. - O Abstração: O uso direto de
AsyncLocal<T>acopla seu código a uma implementação específica, tornando-o mais difícil de otimizar ou alterar no futuro. - Gerenciamento de tempo de vida: o pacote AsyncState fornece melhor controle sobre o tempo de vida dos dados ambientes por meio de APIs explícitas.
O Microsoft.Extensions.AsyncState pacote resolve essas 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 a injeção de dependência para facilitar o teste e a configuração.
Comece agora
Para começar com o gerenciamento de estado assíncrono, instale o pacote NuGet Microsoft.Extensions.AsyncState.
dotnet add package Microsoft.Extensions.AsyncState
Para obter mais informações, consulte dotnet add package ou Gerenciar as dependências de pacotes em aplicativos .NET.
Registrar serviços de estado assíncrono
Registre os serviços de estado assíncrono com seu contêiner de injeção de dependência usando o método de extensão AddAsyncState.
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddAsyncState();
ServiceProvider provider = services.BuildServiceProvider();
Esse registro disponibiliza as interfaces IAsyncContext<T> e IAsyncState para injeção de dependência.
Usar 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 valor definido no contexto flui por meio de operações assíncronas, tornando-o disponível para todos os códigos em execução no mesmo contexto assíncrono.
Usar IAsyncState
A IAsyncState interface é a interface de ciclo de vida base que IAsyncContext<T> estende. Ele fornece Initialize() e Reset() métodos para gerenciar o ciclo de vida de estado assíncrono. Para acesso tipado a valores de estado assíncrono, use IAsyncContext<T> em seu lugar.
Exemplo prático: solicitar correlação
Um caso de uso comum para o estado assíncrono é manter informações de correlação em uma solicitação 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, a ID de correlação é definida uma vez no início do processamento da solicitação e está automaticamente disponível em todas as operações assíncronas subsequentes sem a necessidade de passá-la como um parâmetro.
integração ASP.NET Core
Em aplicativos ASP.NET Core, você pode usar o estado assíncrono para fluir informações específicas da solicitação por meio de seu aplicativo:
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; }
}
Práticas recomendadas
Ao usar o estado assíncrono, considere as seguintes práticas recomendadas:
- Limitar o tamanho do estado: mantenha os objetos de estado assíncronos pequenos para reduzir a sobrecarga de memória e manter o desempenho.
- Inicializar o estado antecipadamente: defina valores de estado assíncrono o mais cedo possível para garantir que eles estejam disponíveis para todas as operações assíncronas downstream.
- Estado de limpeza: redefinir ou limpar o estado assíncrono quando ele não for mais necessário para evitar vazamentos de memória em aplicativos de longa execução.
-
Use interfaces apropriadas: use
IAsyncContext<T>para obter e definir valores tipados no contexto assíncrono atual. UseIAsyncStatequando precisar gerenciar diretamente o ciclo de vida de inicialização e redefinição. - Type safety: crie tipos de contexto específicos em vez de usar dicionários genéricos para manter a segurança do tipo e melhorar a clareza do código.
Consulte também
- injeção de dependência em .NET
- AsyncLocal<T>
- ASP.NET Core middleware