Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should you await a Task?

Say I have a Repository class which has a DbContext. In this class I have a method:

public async Task<T> CreateAsync(T obj)
{
    var o = _dbSet.Add(obj);
    await _dbContext.SaveChangesAsync();
    return o;
}

In a Service class I use this method to create an object:

public async Task<MyObject> Create()
{
    return await _repository.CreateAsync(new MyObject());
}

And finally in my api controller MyObjectController I return this object like so:

public async Task<IHttpActionResult> Get()
{
    return Ok(await _service.Create());
}

I'm confused about all these async and await keywords. I know that a Task is awaitable. Does this mean that I could just return the Task from CreateAsync without awaiting in neither CreateAsync or Create and then finally await it in Get? Does it have a negative effect on my application that I do my awaits like in the example?

like image 991
transporter_room_3 Avatar asked May 30 '15 12:05

transporter_room_3


1 Answers

Does this mean that I could just return the Task from CreateAsync without awaiting in neither CreateAsync or Create and then finally await it in Get?

yes you can do that, it is actually more efficient. if you do your awaits as you are doing them, each asynchronous method will generate a state machine which means more code and more context switching

Does it have a negative effect on my application that I do my awaits like in the example?

There will be a slight performance penalty due to the state machine and the context switching. The cost is typically much less than the cost of the call, but it all adds up in the end. Async Performance: Understanding the Costs of Async and Await is a great article about this topic.

As pointed out by @Richard Szalay, just make sure that you eventually await the task otherwise any exceptions that occur will remain unobserved and will be swallowed.

like image 118
NeddySpaghetti Avatar answered Nov 11 '22 03:11

NeddySpaghetti