问题描述
我为我的api调用创建了FileResult : IHttpActionResult
webapi返回类型. FileResult从另一个URL下载文件,然后将流返回给客户端.
I created a FileResult : IHttpActionResult
webapi return type for my api calls. The FileResult downloads a file from another url and then returns the stream to the client.
最初,我的代码具有using
语句,如下所示:
Initially my code had a using
statement like below:
public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
try
{
HttpResponseMessage response;
using (var httpClient = new HttpClient())
{
response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new System.Net.Http.StreamContent(
await httpClient.GetStreamAsync(this.filePath))
};
}
return response;
}
catch (WebException exception)
{...}
}
但是,这会间歇性地导致TaskCanceledException
.我知道,如果在异步调用完成之前处理HttpClient,则Task的状态将更改为Canceled.但是,由于我在Content = new System.Net.Http.StreamContent(await httpClient.GetStreamAsync(this.filePath))
中使用了 await ,因此应防止HttpClient在任务完成过程中被丢弃.
However this would intermittently cause a TaskCanceledException
. I know that if the HttpClient is disposed before the asychronous call is finished the Task's state will change to canceled. However since I use an await in: Content = new System.Net.Http.StreamContent(await httpClient.GetStreamAsync(this.filePath))
that should prevent the HttpClient from being disposed off in the middle of the task completion.
为什么该任务被取消?不是因为超时,因为它发生在最小的请求上,而并不总是发生在大请求上.
Why does that task get canceled? It is not because of a timeout since this has happened on the smallest requests and doesn't always occur on large requests.
当我删除using
语句时,代码可以正常工作:
When I removed the using
statement the code worked properly:
public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
try
{
HttpResponseMessage response;
var httpClient = new HttpClient();
response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new System.Net.Http.StreamContent(
await httpClient.GetStreamAsync(this.filePath))
};
return response;
}
catch (WebException exception)
{...}
}
您知道为什么使用会导致此问题吗?
Any idea why the using caused the issue?
推荐答案
但是该任务做什么?它获得流.因此,您的代码最终以Stream
结尾,当它关闭HttpClient
时,它可能会完全读取,也可能不会完全读取.
But what does that task do? It gets the stream. So, your code ends up with a Stream
that may or may not be completely read when it closes the HttpClient
.
HttpClient
是专门为重用(和同时使用)设计的,因此,我建议完全删除using
并将HttpClient
声明移到static
类成员.但是,如果要关闭并重新打开客户端,则应该通过在关闭HttpClient
之前将流完全读入内存中来使它正常工作.
HttpClient
is specifically designed for reuse (and simultaneous use), so I recommend removing the using
completely and moving the HttpClient
declaration to a static
class member. But if you want to close and reopen the clients, you should be able to get it working by reading the stream entirely into memory before closing the HttpClient
.
这篇关于HttpClient在using语句中导致Task被取消的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!