HttpClient在响应流完全读取之前被释放,导致连接关闭异常



我正在尝试将请求的响应流式传输到响应。所以基本上是通过管道将请求发送到另一个url。这是我的代码,它说明了我正在尝试做什么

public async Task<IActionResult> GetArticleImage(string userId, string articleId)
{
var imageUrl = "https://image-url"; // This url is retrieved from the database
var imageResult = await this.httpClient.GetAsync(imageUrl);
var stream = await imageResult.Content.ReadAsStreamAsync();
return new FileStreamResult(stream, imageResult.Content.Headers.GetValues("Content-Type").First());
}

在这种情况下,会抛出一个ConnectionResetException,其中包含消息The client has disconnected

我相信发生这种情况是因为请求作用域是在流被完全读取之前处理的,这也处理了HttpClient
当使用var scope = IServiceScopeFactory.CreateScope()(伪代码,实际上是通过构造函数注入的IServiceScopeFactory serviceScopeFactory(创建自定义作用域时,HttpClient通过该作用域进行解析,并且未被释放(既不是作用域也不是客户端(,它可以正常工作。

值得一提的是,方法GetArticleImage是在一个单独的服务类中实现的,而不是控制器中的
以前它是在控制器类中实现的,代码在其中完美地工作
这让我认为作用域处置机制的工作方式略有不同,但我不知道是怎么回事。

HttpClient被注册为singleton,这应该确保它没有被丢弃。

问题是:如何将请求通过管道/流式传输到另一个url

调用此方法的端点可以经常被调用,同时有许多请求,所以我希望避免必须将响应缓存在内存中才能传递。

有时,当外部服务与不正确工作时,会发生这种情况。网络异步/等待

我找到了变通方法(这不是最佳实践(,但它对我有效。

public Task<IActionResult> GetArticleImage(string userId, string articleId)
{
var imageUrl = "https://image-url"; // This url is retrieved from the database
var imageResult = this.httpClient.GetAsync(imageUrl).GetAwaiter().GetResult();
var stream = imageResult.Content.ReadAsStreamAsync().GetAwaiter().GetResult();
return new FileStreamResult(stream, imageResult.Content.Headers.GetValues("Content-Type").First());
}

最新更新