首页 > 解决方案 > query.wait 没有完成

问题描述

我是 MVC C# 中异步方法的新手,所以我尝试了本教程中的一些示例

所以我用一种保存方法编写了一个类creditcardtoken

public  async Task<CreditCardToken> RegisterCardTokenAsync(CreditCardToken creditCardToken)
{
    if (creditCardToken == null) return null;
    creditCardToken.number = creditCardToken.maskedNumber;
    _dbContext.CreditCardToken.Add(creditCardToken);
    var saveChanges = await (_dbContext.SaveChangesAsync());
    if (saveChanges > 0) return creditCardToken;
    else return null;
}

我的控制器有一个调用我的方法registerCardTokenAsync

[HttpPost]
public ActionResult IngresarTargeta(CreditCardViewModel creditCardViewModel)
{
    //do something here....
    //do another thing....

    var query = MyClass.RegisterCardTokenAsync(creditCardToken);
    query.Wait();
 }

理论上,我们使用query.Wait()“等待”直到操作完成。我的问题是在我的数据库CreditCardToken中保存了,但是,我的应用程序只是冻结了。

为什么会发生这种情况,我该如何解决?

据我所知,执行时需要等待FirstOrDefaultAsync()

标签: c#entity-frameworkasync-await

解决方案


不要同步等待async调用,除非您完全了解上下文,否则请async传播。

public async Task<ActionResult> IngresarTargeta(CreditCardViewModel creditCardViewModel)
{
   var result = await MyClass.RegisterCardTokenAsync(creditCardToken)

这就是为什么

  • 顶级方法调用RegisterCardTokenAsync(在 ASP.NET 上下文中)。

  • RegisterCardTokenAsync_dbContext.SaveChangesAsync()通过调用(仍在上下文中)开始保存更改 。

  • SaveChangesAsync返回一个 uncompleted Task,表示保存未完成。

  • RegisterCardTokenAsync等待Task返回的SaveChangesAsync. 上下文被捕获并将用于SaveChangesAsync稍后继续运行该方法。SaveChangesAsync返回一个 uncompleted Task,表示该SaveChangesAsync方法不完整。

  • 顶级方法在Task返回时同步阻塞SaveChangesAsync. 这会阻塞上下文线程。

...

  • 最终,SaveChangesAsync遗嘱完成。这完成了TaskSaveChangesAsync.

  • 继续 forRegisterCardTokenAsync现在准备好运行,它等待上下文可用(因此它可以在上下文中执行)。

这会导致死锁。顶级方法正在阻塞等待RegisterCardTokenAsync完成的上下文线程,并RegisterCardTokenAsync等待释放上下文以便它可以完成。


推荐阅读