Обработка TaskCanceledException с помощью IExceptionHandlerC#

Место общения программистов C#
Ответить
Anonymous
 Обработка TaskCanceledException с помощью IExceptionHandler

Сообщение Anonymous »

Я пытаюсь реализовать общий тайм-аут для своих запросов на C#. Мне известно о промежуточном программном обеспечении тайм-аута запроса, но ему нельзя дать указание повторно создать исключение. Поэтому я начал с простого:

Код: Выделить всё

public class CancelInTimeMiddleware : IMiddleware
{
// Better understanding of why we can't stop all requests very easiliy: https://stackoverflow.com/a/52660992/619465
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var originalCt = context.RequestAborted;
using (var timoutTS = CancellationTokenSource.CreateLinkedTokenSource(originalCt))
{
timoutTS.CancelAfter(10000);       // Always cancel after 10 seconds
context.RequestAborted = timoutTS.Token;
await next(context);
}
}
}
И простая конечная точка:

Код: Выделить всё

    public static async Task GetTimer(int delaySeconds, CancellationToken cancellationToken)
{
logger.LogInformation("Entering the wait!");
await Task.Delay(delaySeconds * 1000, cancellationToken);

//catch (TaskCanceledException) -> I also want to handle cases where this is forgotten.

return Results.Json(new { Message = "Waiting is done" });
}
Поэтому я добавил этот простой IExceptionHandler (спасибо):

Код: Выделить всё

class SimpleExceptionHandler : IExceptionHandler
{
public async ValueTask TryHandleAsync(
HttpContext httpContext,
Exception exception,
CancellationToken cancellationToken)
{
// Your response object
var error = new { message = exception.Message };
await httpContext.Response.WriteAsJsonAsync(error, cancellationToken);
return true;
}
}
И зарегистрировал его так:

Код: Выделить всё

builder.Services.AddProblemDetails();
builder.Services.AddExceptionHandler();
builder.Services.AddSingleton();

var app = builder.Build();
app.UseExceptionHandler(_ => { });
app.UseMiddleware();
app.MapGet("wait/{delaySeconds:int}", TestEndPointsImplementations.GetTimer);
app.Run();

Это работает для других исключений, которые я выбрасываю: но не тогда, когда выполняется отмена. Это потому, что конвейер запросов останавливается при срабатывании CancellationToken?


Подробнее здесь: https://stackoverflow.com/questions/792 ... ionhandler
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»