Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

query.wait is not finishing

I am new with async methods in MVC C#, so I tried some examples from This tutorial

So I coded a class with a method for saving 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;
}

My controller has a method that calls my registerCardTokenAsync

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

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

In theory we use query.Wait() to "wait" until the operation is finished. My problem is that in my database the CreditCardToken is saved, however, my application just freezes.

Why is this happening and how can I solve it?

As far as I know await is required when executing FirstOrDefaultAsync().

like image 566
ev vk Avatar asked Dec 06 '25 04:12

ev vk


1 Answers

Don't synchronously wait on async calls, unless you are completely aware of the context, let async propagate .

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

Here is why

  • The top-level method calls RegisterCardTokenAsync (within the ASP.NET context).

  • RegisterCardTokenAsync starts the save changes by calling _dbContext.SaveChangesAsync() (still within the context).

  • SaveChangesAsync returns an uncompleted Task, indicating the save is not complete.

  • RegisterCardTokenAsync awaits the Task returned by SaveChangesAsync. The context is captured and will be used to continue running the SaveChangesAsync method later. SaveChangesAsync returns an uncompleted Task, indicating that the SaveChangesAsync method is not complete.

  • The top-level method synchronously blocks on the Task returned by SaveChangesAsync. This blocks the context thread.

...

  • Eventually, the SaveChangesAsync will complete. This completes the Task that was returned by SaveChangesAsync.

  • The continuation for RegisterCardTokenAsync is now ready to run, and it waits for the context to be available (so it can execute in the context).

This results in a deadlock. The top-level method is blocking the context thread waiting for RegisterCardTokenAsync to complete, and RegisterCardTokenAsync is waiting for the context to be freed so it can complete.

like image 170
TheGeneral Avatar answered Dec 08 '25 17:12

TheGeneral