Scadenze, annullamento e interceptor
Applichi timeout con le scadenze, propaghi CancellationToken e aggiunga funzionalità trasversali tramite gli interceptor di gRPC.
Scadenze, annullamento e interceptor è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.
Affidabilità in gRPC: scadenze e annullamento
I servizi gRPC in produzione devono gestire due aspetti critici dell'affidabilità: le scadenze (per quanto tempo il client attenderà) e l'annullamento (l'interruzione anticipata del lavoro). Insieme, impediscono l'esaurimento delle risorse e i guasti a cascata.
Impostare una scadenza per una chiamata
Una scadenza è un istante assoluto entro il quale la chiamata deve essere completata. La imposti con CallOptions. Se viene superata, il server riceve un annullamento e il client ottiene 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);Gestire DeadlineExceeded nel client
Intercetti RpcException e controlli il codice di stato per distinguere la scadenza della deadline dagli altri errori.
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}");
}Rispettare le scadenze sul server
Il server dovrebbe controllare context.CancellationToken durante le operazioni prolungate. Quando la scadenza viene superata, questo token viene annullato 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);
}Propagazione di CancellationToken
Propaghi sempre il token di annullamento del server lungo tutta la catena di chiamate asincrone. Se lo ignora, le chiamate annullate continuano a consumare risorse inutilmente.
// 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 deadlineIntercettori gRPC: concetto
Gli intercettori sono l'equivalente gRPC del middleware di ASP.NET Core: vengono eseguiti prima o dopo le chiamate RPC e possono esaminare o modificare richieste, risposte ed eccezioni. Sono ideali per logging, autenticazione e logica di retry.
Creare un intercettore lato server
Erediti da Interceptor ed esegua l'override del tipo di metodo che desidera intercettare. Chiami continuation per proseguire fino al gestore effettivo.
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;
}
}Registrare gli intercettori del server
Registri gli intercettori globalmente (per tutti i servizi) oppure per singolo servizio in Program.cs. Il contenitore DI risolve le dipendenze del costruttore.
// 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>();Intercettori lato client
Gli intercettori client avvolgono le chiamate in uscita: sono utili per aggiungere intestazioni di autenticazione, logica di retry o ID di correlazione senza modificare ogni punto di chiamata.
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);Intercettore delle eccezioni
Un intercettore delle eccezioni lato server converte le eccezioni non gestite in RpcExceptions, impedendo la divulgazione di dettagli interni ai client.
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 rapida
Cosa accade quando una chiamata gRPC supera la propria scadenza?
Riepilogo: scadenze, annullamento e intercettori
Punti chiave:
- Imposti sempre le scadenze sulle chiamate client per evitare attese senza limite
- Controlli
context.CancellationTokensul server e lo passi a tutte le chiamate asincrone - Gli intercettori gestiscono gli aspetti trasversali (logging, autenticazione, mappatura degli errori) senza appesantire il codice del servizio
- Intercettori del server: esegua l'override dei metodi del gestore Unary/Stream e chiami
continuation - Intercettori client: li colleghi alla catena degli invoker del canale
Domande Frequenti
La lezione «Scadenze, annullamento e interceptor» è gratuita?
Sì — il testo completo di «Scadenze, annullamento e interceptor» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.
Cosa imparerò in «Scadenze, annullamento e interceptor»?
Applichi timeout con le scadenze, propaghi CancellationToken e aggiunga funzionalità trasversali tramite gli interceptor di gRPC. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C# Academy?
Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Scadenze, annullamento e interceptor»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C# Academy?
Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Fondamenti di gRPC e Protobuf
- RPC unarie e streaming dal server
- Streaming dal client e bidirezionale
- Scadenze, annullamento e interceptor