我为我的api调用创建了FileResult : IHttpActionResult webapi返回类型。 FileResult从另一个URL下载文件,然后将流返回给客户端。

最初,我的代码有一个using语句,如下所示:

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)),应防止HttpClient在任务完成过程中被丢弃。

为什么该任务被取消? 并不是因为超时,因为这发生在最小的请求上,并不总是发生在大请求上。

当我删除using语句时,代码可以正常工作:
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)
    {...}
}

知道为什么使用引起了问题吗?

最佳答案



但是那个任务是做什么的呢?它得到流。因此,您的代码以Stream结尾,当关闭HttpClient时,它可能会或可能不会完全读取。
HttpClient是专门为重用(和同时使用)而设计的,因此,我建议完全删除using并将HttpClient声明移至static类成员。但是,如果您想关闭并重新打开客户端,则应该可以通过在关闭HttpClient之前将流完全读入内存来使其工作。

10-05 21:09
查看更多