ASP.Net MVC中调用Face API异步方法出现无限等待及页面刷新问题
解决ASP.NET MVC中Face API异步调用无限等待及页面刷新问题
我在处理ASP.NET MVC异步代码时经常碰到这种死锁情况,你的问题大概率是异步流程未正确处理导致的上下文死锁,进而引发请求超时、页面自动刷新。下面给你拆解原因和修复方案:
核心原因
ASP.NET MVC有自己的SynchronizationContext,当你在非异步标记的Action里调用await,或者在异步流程中混用.Result/.Wait()这类同步阻塞方法时,会触发上下文死锁:任务需要等待上下文释放才能继续,而上下文又在等待任务完成,最终形成无限等待,页面因请求超时自动刷新。
具体修复步骤
- 确保控制器Action是异步方法:必须用
async修饰,返回类型指定为Task<ActionResult>(不能是void或同步返回类型),让ASP.NET框架能正确调度异步流程。 - 移除所有同步阻塞调用:检查整个调用链,绝对不要用
faceclient.CreatePersonAsync(...).Result或.Wait(),全程用await来等待异步任务。 - 添加
ConfigureAwait(false)避免上下文绑定:在异步调用后加上这个配置,告诉Task不需要回到原同步上下文,从根源避免死锁风险。
修正后的代码示例
// 控制器Action必须标记为异步 public async Task<ActionResult> CreatePerson(string name) { // 静态FaceServiceClient官方SDK是线程安全的,可放心使用 static Microsoft.ProjectOxford.Face.FaceServiceClient faceclient = new Microsoft.ProjectOxford.Face.FaceServiceClient(subscriptionKey); // 加入ConfigureAwait(false)避免死锁 var face = await faceclient.CreatePersonAsync(PersonGroupID, name).ConfigureAwait(false); var personid = face.PersonId; // 后续业务逻辑示例:将结果传递到视图 ViewBag.PersonId = personid; return View(); }
额外注意事项
- 如果在服务层等其他地方也调用了Face API的异步方法,同样要遵循异步流程,全程用
await,不要混用同步阻塞。 - 页面刷新的本质是请求超时,解决死锁后请求能正常完成,页面就不会自动刷新了。
内容的提问来源于stack exchange,提问作者Arnab Chakraborty
相关产品推荐
相关产品推荐

