一个方法调用了async方法,要将这个方法本身设计为async。
public class BlogController : Controller
{
public async Task<ActionResult> AwaitDemo()
{
//虽然写了async,但是没有await,所以还是同步
var responseHtml = GetResponseHtml("http://www.cnblogs.com/");
return Content(responseHtml);
}
//同步方法
private string GetResponseHtml(string url)
{
//调用了异步方法,而且用Result获取返回值
return GetResponseContentAsync(url).Result;
}
//异步方法 async/await
private async Task<string> GetResponseContentAsync(string url)
{
var httpClient = new System.Net.Http.HttpClient();
var response = await httpClient.GetAsync(url);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
return await response.Content.ReadAsStringAsync();
}
else
{
return "error";
}
}
}
运行程序,一致卡死,而在控制台应用程序中调用同样的GetResponseHtml,不会出现问题,因为控制台没有同步上下文SynchronizationContext
,而ASP.NET程序有同步上下文AspNetSynchronizationContext,异步执行完后,找到前边的AspNetSynchronizationContext。
改造方法:
1、开启Task,进行await
GetResponseHtml方法还是同步,而AwaitDemo,变成了异步
public async Task<ActionResult> AwaitDemo()
{
var responseHtml = await Task.Factory.StartNew(() =>
GetResponseHtml("http://www.cnblogs.com/"));
return Content(responseHtml);
}
2、将GetResponseHtml变成异步方法
异步到底
public async Task<ActionResult> AwaitDemo()
{
var responseHtml = await GetResponseHtml("http://www.cnblogs.com/");
return Content(responseHtml);
} private async Task<string> GetResponseHtml(string url)
{
return await GetResponseContentAsync(url);
}