0Pricing
C# Academy · Aula

Prazos, cancelamento e interceptadores

Aplique timeouts com prazos, propague CancellationToken e adicione preocupações transversais por meio de interceptadores gRPC.

Prazos, cancelamento e interceptadores é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.

Confiabilidade no gRPC: prazos e cancelamento

Os serviços gRPC em produção precisam lidar com duas questões essenciais de confiabilidade: prazos (por quanto tempo o cliente aguardará) e cancelamento (interrupção antecipada do trabalho). Juntos, eles evitam o esgotamento de recursos e falhas em cascata.

Definindo um prazo para uma chamada

Um prazo é um instante absoluto até o qual a chamada deve ser concluída. Defina-o com CallOptions. Se ele for ultrapassado, o servidor receberá um cancelamento e o cliente obterá StatusCode.DeadlineExceeded.

var deadline = DateTime.UtcNow.AddSeconds(5);

var reply = await client.GetOrderAsync(
    new GetOrderRequest { Id = 42 },
    deadline: deadline);

// Or via CallOptions:
var options = new CallOptions(deadline: deadline);
var reply2 = await client.GetOrderAsync(
    new GetOrderRequest { Id = 42 }, options);

Tratando DeadlineExceeded no cliente

Capture RpcException e verifique o código de status para diferenciar a expiração do prazo de outros erros.

try
{
    var reply = await client.GetOrderAsync(
        new GetOrderRequest { Id = 42 },
        deadline: DateTime.UtcNow.AddSeconds(3));
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.DeadlineExceeded)
{
    Console.WriteLine("Call timed out");
}
catch (RpcException ex)
{
    Console.WriteLine($"gRPC error: {ex.Status.Detail}");
}

Respeitando os prazos no servidor

O servidor deve verificar context.CancellationToken durante trabalhos longos. Quando o prazo expira, esse token é cancelado automaticamente.

public override async Task<ReportResponse> GenerateReport(
    ReportRequest request,
    ServerCallContext context)
{
    var ct = context.CancellationToken;

    // Pass ct to every async call — work stops when deadline hits
    var data = await _db.FetchLargeDatasetAsync(request.Filters, ct);
    var report = await _reportEngine.BuildAsync(data, ct);

    ct.ThrowIfCancellationRequested(); // explicit check before CPU work
    return MapToResponse(report);
}

Propagação de CancellationToken

Sempre propague o token de cancelamento do servidor por toda a cadeia de chamadas assíncronas. Se você ignorá-lo, as chamadas canceladas continuarão consumindo recursos desnecessariamente.

// GOOD: token flows through the call chain
await _db.Products.AsNoTracking()
    .Where(p => p.IsActive)
    .ToListAsync(context.CancellationToken); // cancels if client disconnects

// BAD: ignores cancellation
await _db.Products.ToListAsync(); // keeps running after deadline

Interceptadores gRPC: conceito

Os interceptadores são o equivalente gRPC dos componentes intermediários do ASP.NET Core: eles são executados antes ou depois das chamadas RPC e podem inspecionar ou modificar solicitações, respostas e exceções. São ideais para registro, autenticação e lógica de repetição.

Criando um interceptador no servidor

Herede de Interceptor e substitua o tipo de método que deseja interceptar. Chame continuation para prosseguir até o manipulador real.

using Grpc.Core.Interceptors;

public class LoggingInterceptor : Interceptor
{
    private readonly ILogger<LoggingInterceptor> _logger;
    public LoggingInterceptor(ILogger<LoggingInterceptor> l) => _logger = l;

    public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
        TRequest request,
        ServerCallContext context,
        UnaryServerMethod<TRequest, TResponse> continuation)
    {
        _logger.LogInformation("gRPC call: {Method}", context.Method);
        var sw = System.Diagnostics.Stopwatch.StartNew();
        var response = await continuation(request, context);
        _logger.LogInformation("Completed in {Ms}ms", sw.ElapsedMilliseconds);
        return response;
    }
}

Registrando interceptadores no servidor

Registre os interceptadores globalmente (em todos os serviços) ou por serviço em Program.cs. O contêiner de DI resolve as dependências do construtor.

// Globally for all gRPC services:
builder.Services.AddGrpc(opt =>
    opt.Interceptors.Add<LoggingInterceptor>());

// Or per service:
builder.Services.AddGrpc();
builder.Services.AddSingleton<LoggingInterceptor>();

app.MapGrpcService<OrderService>()
   .AddInterceptor<LoggingInterceptor>();

Interceptadores no cliente

Os interceptadores do cliente envolvem as chamadas de saída — são úteis para adicionar cabeçalhos de autenticação, lógica de repetição ou identificadores de correlação sem modificar cada ponto de chamada.

public class AuthInterceptor : Interceptor
{
    private readonly ITokenProvider _tokens;
    public AuthInterceptor(ITokenProvider t) => _tokens = t;

    public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
        TRequest request,
        ClientInterceptorContext<TRequest, TResponse> context,
        AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
    {
        var headers = context.Options.Headers ?? new Metadata();
        headers.Add("authorization", $"Bearer {_tokens.GetToken()}");
        var newContext = new ClientInterceptorContext<TRequest, TResponse>(
            context.Method, context.Host,
            context.Options.WithHeaders(headers));
        return continuation(request, newContext);
    }
}

// Attach to channel:
var invoker = channel.Intercept(new AuthInterceptor(tokenProvider));
var client = new OrderService.OrderServiceClient(invoker);

Interceptador de exceções

Um interceptador de exceções no servidor converte exceções não tratadas em RpcExceptions, impedindo que detalhes internos sejam expostos aos clientes.

public class ExceptionInterceptor : Interceptor
{
    public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
        TRequest request,
        ServerCallContext context,
        UnaryServerMethod<TRequest, TResponse> continuation)
    {
        try
        {
            return await continuation(request, context);
        }
        catch (NotFoundException ex)
        {
            throw new RpcException(new Status(StatusCode.NotFound, ex.Message));
        }
        catch (Exception ex)
        {
            throw new RpcException(new Status(StatusCode.Internal, "Internal error"));
        }
    }
}

Verificação rápida

O que acontece quando uma chamada gRPC ultrapassa o prazo?

Recapitulação: prazos, cancelamento e interceptadores

Principais conclusões:

  • Sempre defina prazos nas chamadas do cliente para evitar esperas sem limite
  • Verifique context.CancellationToken no servidor e passe-o para todas as chamadas assíncronas
  • Os interceptadores tratam questões transversais (registro, autenticação e mapeamento de erros) sem poluir o código do serviço
  • Interceptadores do servidor: substitua os métodos de tratamento Unary/Stream e chame continuation
  • Interceptadores do cliente: associe-os à cadeia de invocadores do canal

Perguntas Frequentes

A aula “Prazos, cancelamento e interceptadores” é grátis?

Sim — o texto completo de “Prazos, cancelamento e interceptadores” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.

O que vou aprender em “Prazos, cancelamento e interceptadores”?

Aplique timeouts com prazos, propague CancellationToken e adicione preocupações transversais por meio de interceptadores gRPC. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C# Academy?

Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Prazos, cancelamento e interceptadores”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C# Academy?

Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Fundamentos de gRPC e Protobuf
  2. RPCs unários e transmissão pelo servidor
  3. Transmissão pelo cliente e bidirecional
  4. Prazos, cancelamento e interceptadores
← Voltar para C# Academy