Я работаю над действием основного контроллера asp. net, которое предоставляет поток в течение X секунд или до отмены в зависимости от того, что произойдет первым.
Мой первый подход заключался в асинхронном копировании потока в ответ, таким образом, я довольно легко могу использовать токен отмены, передав его в CopyToAsyn c.
[HttpGet]
[Route("getstream1")]
public async Task GetStream1(CancellationToken cancellationToken)
{
var stream = await new HttpClient().GetStreamAsync("http://localhost:4747/video");
var cst = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
var ct = cst.Token;
Response.OnStarting(() =>
{
cst.CancelAfter(5000);
return Task.CompletedTask;
});
Response.StatusCode = 200;
Response.ContentType = "video/stream";
await Response.StartAsync(ct);
try
{
await stream.CopyToAsync(Response.Body, 1024, ct);
}
catch (Exception ex)
{
if (ex is TaskCanceledException || ex is OperationCanceledException)
{
return;
}
throw;
}
}
Моя вторая идея состояла в том, чтобы вернуть его как ответ файлового потока и запустить и забыть задачу, которая ожидает заданное количество времени и прерывает HttpContext или отменяется пользователем с помощью токена отмены.
[HttpGet]
[Route("getstream2")]
public async Task<IActionResult> GetStream2(CancellationToken cancellationToken)
{
var stream = await new HttpClient().GetStreamAsync("http://localhost:4747/video");
Task.Factory.StartNew(async () =>
{
await Task.Delay(5000, cancellationToken);
try
{
HttpContext.Abort();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}, cancellationToken).ContinueWith(task =>
{
// handle exception
}
);
return new FileStreamResult(stream, "video/stream");
}
Мой вопрос. Один из этих подходов лучше, чем другой? Есть ли лучший способ реализовать это? Можно ли позвонить Abort
на HttpContext
, когда я хочу закончить свой ответ?