我有一个Web服务(在Asp.net Web API中制作),它返回一个大小约为10MB的xml文件。
该服务已经过Fiddler测试,并且正在运行
我正在尝试使用HttpClient类下载该文件。问题是编译器永远不会超出await client.GetAsync()
方法,即使API项目返回HttpResponseMessage
。
这是我的功能
public async Task<XDocument> DownloadXmlAsync(string xmlFileName)
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:51734/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
// When the copiler enters this next command, it doesn't get outside anymore
HttpResponseMessage response = await client.GetAsync("api/applications/ApplicationXml?fileName=" + xmlFileName);
response.EnsureSuccessStatusCode();
string stringResponse = await response.Content.ReadAsStringAsync();
XDocument xDoc = new XDocument(stringResponse);
return xDoc;
}
}
我还更新了web.config中的maxRequestLength
<httpRuntime maxRequestLength="15360" />
我做错了什么?
修改
调用函数
public async Task<ActionResult> Index()
{
var xmlTask = DownloadXmlAsync("1.xml");
// doesn't reach here
var result = xmlTask.Result;
return View();
}
答案 0 :(得分:4)
通过调用Result
导致经典死锁。相反,您应该await
任务:
public async Task<ActionResult> Index()
{
var xmlTask = DownloadXmlAsync("1.xml");
// doesn't reach here
var result = await xmlTask;
return View();
}
I explain this deadlock in full on my blog,但总的想法是这样的:
await
Task
时,编译器将捕获“上下文”并在Task
完成时使用它来恢复该方法。对于ASP.NET,此“上下文”是请求上下文。DownloadXmlAsync
(异步)等待GetAsync
完成时,它会将未完成的任务返回给Index
。Index
同步阻止该任务。这意味着请求线程将被阻止,直到该任务完成。GetAsync
完成。但是,DownloadXmlAsync
无法继续,因为它正在尝试恢复该“上下文”,并且“上下文”中已经有一个线程:在该任务上被阻止的那个。