Deadlines, annullering og interceptors
Anvend timeouts med deadlines, propagér CancellationToken, og tilføj tværgående funktionalitet via gRPC-interceptors.
Deadlines, annullering og interceptors er en gratis C# Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C# Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C# Academy-kurset indeholder 4 lektioner i alt.
Pålidelighed i gRPC: deadlines og annullering
gRPC-tjenester i produktion skal håndtere to kritiske aspekter af pålidelighed: deadlines (hvor længe klienten venter) og annullering (at stoppe arbejdet tidligt). Tilsammen forhindrer de ressourceudtømning og kaskadefejl.
Angivelse af en deadline for et kald
En deadline er et absolut tidspunkt, hvor kaldet senest skal være afsluttet. Angiv den med CallOptions. Hvis den overskrides, modtager serveren en annullering, og klienten får 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);Håndtering af DeadlineExceeded på klienten
Indfang RpcException, og kontrollér statuskoden for at skelne mellem udløbet af en deadline og andre fejl.
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}");
}Overholdelse af deadlines på serveren
Serveren bør kontrollere context.CancellationToken under langvarigt arbejde. Når deadlinen overskrides, annulleres dette token automatisk.
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);
}Videreførsel af CancellationToken
Viderefør altid serverens CancellationToken gennem alle kæder af asynkrone kald. Hvis du ignorerer det, fortsætter annullerede kald unødvendigt med at bruge ressourcer.
// 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 deadlinegRPC-interceptorer: konceptet
Interceptorer er gRPC's pendant til ASP.NET Core-middleware — de kører før og efter RPC-kald og kan inspicere eller ændre anmodninger, svar og undtagelser. De er ideelle til logning, godkendelse og genforsøgslogik.
Oprettelse af en serverinterceptor
Nedarv fra Interceptor, og tilsidesæt den type metode, du vil interceptere. Kald continuation for at fortsætte til den faktiske behandler.
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;
}
}Registrering af serverinterceptorer
Registrér interceptorer globalt (for alle tjenester) eller pr. tjeneste i Program.cs. DI-containeren løser konstruktørens afhængigheder.
// 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>();Klientinterceptorer
Klientinterceptorer omslutter udgående kald — nyttigt til at tilføje godkendelsesheadere, genforsøgslogik eller korrelations-id'er uden at ændre hvert enkelt kaldested.
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);Undtagelsesinterceptor
En undtagelsesinterceptor på serversiden konverterer ikke-håndterede undtagelser til RpcExceptions, så interne detaljer ikke lækkes til klienterne.
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"));
}
}
}Hurtigt tjek
Hvad sker der, når et gRPC-kald overskrider sin deadline?
Opsummering: deadlines, annullering og interceptorer
Vigtigste pointer:
- Angiv altid deadlines for klientkald for at forhindre ubegrænsede ventetider
- Kontrollér
context.CancellationTokenpå serveren, og giv det videre til alle asynkrone kald - Interceptorer håndterer tværgående hensyn (logning, godkendelse og fejlkortlægning) uden at gøre tjenestekoden rodet
- Serverinterceptorer: tilsidesæt Unary/Stream-behandlermetoder, og kald
continuation - Klientinterceptorer: tilknyt dem til kanalens kaldkæde
Lær C# med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 93
- Lektioner
- 346
Ofte stillede spørgsmål
Er lektionen “Deadlines, annullering og interceptors” gratis?
Ja — hele teksten til “Deadlines, annullering og interceptors” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C# Academy-kurset, skal du opgradere til CoddyKit PRO. C# Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Deadlines, annullering og interceptors”?
Anvend timeouts med deadlines, propagér CancellationToken, og tilføj tværgående funktionalitet via gRPC-interceptors. Du øver dig i C# Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på C# Academy?
Der kræves ingen tidligere erfaring. C# Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.
Hvor lang tid tager lektionen “Deadlines, annullering og interceptors”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne C# Academy-lektion?
Ja. Alle C# Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Grundlæggende om gRPC og Protobuf
- Unary- og server-streaming-RPC'er
- Klient- og bidirektionel streaming
- Deadlines, annullering og interceptors