【发布时间】:2017-08-03 07:40:24
【问题描述】:
我知道在同步 MVC 方法中调用异步方法时存在 TPL 死锁陷阱,同时使用 .Wait() 或 .Result 等待任务完成。
但是我们刚刚在我们的 MVC 应用程序中发现了一个奇怪的行为:同步操作调用了一个异步方法,但由于它是一个触发器,我们从未等待它完成。不过,异步方法似乎卡住了。
代码如下所示,这个奇怪的问题不是 100% 发生的。它只是在某个时候发生。
当它发生时:
- HomeController.Index() 动作完成
- Log.Info("Begin") 已执行。
- SaveToDb() 完成了这项工作,但不知道它是否在完成后挂起。
- PublishTomessageQueue() 没有完成这项工作,不知道它是否从未启动或只是卡在里面。
- 没有调用 Log.Info("Finish")/Log.Error("Error")。
大多数时候,代码按预期工作。
ISomeInterface.Trigger() 也从其他地方调用,Windows 服务而不是 mvc,但这种奇怪的行为从未发生过。
所以我的问题是,即使 没有 .Wait() 也没有 .Result,异步任务是否有可能陷入死锁?
非常感谢。
public interface ISomeInterface
{
Task Trigger();
}
public class SomeClass
{
public async Task Trigger()
{
Log.Info("Begin");
try
{
await SaveToDb();
await PublishToMessageQueue();
Log.Info("Finish");
}
catch (Exception ex)
{
Log.Error("Error");
}
}
}
public class HomeController : Controller
{
public ISomeInterface Some { get; set; }
public ActionResult Index()
{
Some.Trigger(); //<----- The thread is not blocked here.
return View();
}
}
【问题讨论】:
-
我不是很精通MVC,但我好像记得可以制作控制器方法
async,例如:public async Task<ActionResult> Index()。那么你应该可以在Trigger方法上await。 -
@easuter 是的,你是对的。这就是我所做的。我问这个问题的原因是我很好奇这种情况下怎么会发生僵局。
标签: c# asp.net-mvc asynchronous task deadlock