4

I am new to using async and this seems to elude me on what the cause or issue is, when I attempt to load the webpage the async call seems to hang and the page is never loaded. Is my implementation wrong here?

CONTROLLER

public ActionResult Index()
{

    var model = _partyAddOnService.Get().Result.Select(x => new AddOnModel()
    {
        Id = x.Id,
        AddOnType = x.AddOnType,
        Description = x.Description,
        Name = x.Name,
        Price = x.Price
    });

    return View(model);
}

SERVICE

public async Task<IEnumerable<AddOn>> Get()
{
    return await _repository.GetAsync();
}

REPOSITORY

public async Task<IEnumerable<T>> GetAsync()
{
    return await Context.Set<T>().ToListAsync();
}

UPDATE:

I tried this as well and it still hangs...

public ActionResult Index()
{

    var model = _partyAddOnService.Get();
    return View();
}

* When debugging and looking at the Task status it says "Waiting for activation"

Also tried using the ConfigureAwait method as the article suggested. (see James comment below)

public async Task<IEnumerable<AddOn>> Get()
{
    return await _repository.GetAsync().ConfigureAwait(false);
}
11
  • 3
    Your code is deadlocking. Commented Jun 18, 2014 at 15:03
  • 2
    Why are you using async if you want to synchronously obtain the result of the call? Result blocks. Commented Jun 18, 2014 at 15:07
  • I imagine the deadlocking is my controller? Not sure how to fix though. Commented Jun 18, 2014 at 15:10
  • 2
    @usr yeah the more I've been reading about it the more I realize this whole thing is a waste of time and effort. I'll remove it and simply just call the database synchronously. I don't have any methods that rely on multiple calls to the database, EF returns my data with children based on FK automatically so I don't need to call multiple times. I was just trying to be proactive in my code architecture. Darn over-eager junior developer syndrome. Thanks for the help (everyone) Commented Jun 18, 2014 at 15:53
  • 1
    @yycdev a smart choice. Commented Jun 18, 2014 at 15:56

2 Answers 2

7

To prevent deadlocks, just use async all the way up. You're already using it in your service and repository, so just add it to your controller:

public async Task<ActionResult> Index()
{
  var model = (await _partyAddOnService.Get()).Select(x => new AddOnModel()
  {
    Id = x.Id,
    AddOnType = x.AddOnType,
    Description = x.Description,
    Name = x.Name,
    Price = x.Price
  });

  return View(model);
}

I also recommend that you change your async methods to end in Async, to follow the Task-based Asynchronous Pattern. I.e., Get should be GetAsync.

Sign up to request clarification or add additional context in comments.

Comments

1

You are causing a deadlock, because you didn't implement the async-await pattern all the way up. Also use .ConfigureAwait(false) on the lowest level.

public async Task<ActionResult> Index()
{

    var model = await _partyAddOnService.Get().Result.Select(x => new AddOnModel()
    {
        Id = x.Id,
        AddOnType = x.AddOnType,
        Description = x.Description,
        Name = x.Name,
        Price = x.Price
    });

    return View(model);
}

2 Comments

Why did this get downvoted? As someone who is trying to learn and understand async I am curious to know if there is something perhaps if I should know something not to do here?
Using async IO and then blocking defeats the point and gets you the worst of both worlds. @yycdev for that reason your own code doesn't make sense either.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.