asp.net-core - 无法通过 ASP.NET Core 中的 CancellationToken 中断 HttpClient.GetStreamAsync
问题描述
我正在尝试向 AXIS 相机发送 http 请求以接收流。一切正常,除了我无法在不再需要时使用 CancellationToken 取消请求。我有以下架构:
Blazor 客户端:
// LiveCamera.razor
<img src="CameraSystem/getStream" onerror="[...]" alt="">
ASP.NET 核心服务器:
// CameraSystemController.cs
[ApiController]
[Route("[controller]")]
public class CameraSystemController : Controller
{
[HttpGet("getStream")]
public async Task<IActionResult> GetStream()
{
Stream stream = await Device_CameraStandard.GetStream();
if (stream != null) {
Response.Headers.Add("Cache-Control", "no-cache");
FileStreamResult result = new FileStreamResult(stream, _contentTypeStreaming) {
EnableRangeProcessing = true
};
return result;
} else {
return new StatusCodeResult((int)HttpStatusCode.ServiceUnavailable);
}
}
}
访问相机的类:
// Device_CameraStandard.cs
internal class Device_CameraStandard
{
private HttpClient _httpClient;
private static CancellationTokenSource _tokenSource;
private System.Timers.Timer _keepAliveTimer;
internal Device_CameraStandard() {
_keepAliveTimer = new System.Timers.Timer();
_keepAliveTimer.Interval = 3000;
_keepAliveTimer.Elapsed += KeepAliveTimeout;
_tokenSource = new CancellationTokenSource();
[...]
}
internal async Task<Stream> GetStream()
{
return await _httpClient.GetStreamAsync("http://[...]/axis-cgi/mjpg/video.cgi?&camera=1", _tokenSource.Token);
}
// Invoked periodically by client from LiveCamera.razor.cs, not included here
internal void KeepAlive()
{
LLogger.Debug("KeepAlive!");
_keepAliveTimer.Stop();
_keepAliveTimer.Start();
}
private void KeepAliveTimeout(object sender, ElapsedEventArgs e)
{
LLogger.Debug("Timeout!");
_keepAliveTimer.Stop();
_tokenSource.Cancel();
_tokenSource.Dispose();
_tokenSource = new CancellationTokenSource();
}
}
但是,即使所有客户端都离开 LiveCamera.razor 页面并且 _keepAliveTimer 已过并且 CancellationTokenSource 被取消,请求也不会被取消。我可以从带宽使用量没有减少的事实中看出这一点(“接收”带宽,表明服务器仍在从相机接收数据),只有在我关闭浏览器选项卡时才会减少。
你能帮我理解我做错了什么吗?谢谢
编辑:最后,即使遵循了在使用返回流的所有代码部分中观察令牌的建议,包括控制器,我最终发现标签
// LiveCamera.razor
<img src="CameraSystem/getStream" onerror="[...]" alt="">
导致客户端永远不会停止发送请求。因此,我不得不使用一种解决方法来强制客户端在离开 LiveCamera.razor 页面之前停止发送请求。
解决方案
推荐阅读
- javascript - 具有多个学习常数的反向传播算法
- android - OkHttp client.newcall(request).enqueue ...获取空指针
- node.js - 按钮未插入 Pug 的表格行中
- bash - 如何在 bash 上获取命令输出的特定部分
- reactjs - 创建反应应用代理不重定向请求
- image - SVG 形状路径内的图像在 Safari 中呈现为黑色
- c++ - 如何迭代 const 向量
- c++ - STL Map:将一对对象插入到地图中
- vue.js - Vue.js - v-for 指标混淆了?
- wordpress - TinyPNG 压缩图像的木材图像大小调整会产生比原始文件更大的文件