Casey Crookston
Casey Crookston

Reputation: 13965

Wrapping my head around async await

Forgive the blatant newbie question. There is something about async and await that I am not grasping.

In order for a method to be async, it must await a return from task/method that is also async. Correct? But at some point, won't there have to be a task that isn't async or won't await anything?

I've been reading tutorials like these two:

https://msdn.microsoft.com/en-us/magazine/hh456401.aspx

https://msdn.microsoft.com/en-us/library/mt674882.aspx

And I've been looking at a lot of other threads here. But there is still something I don't understand. I'll try and give a simple example. Let's say I want to write a value to a column in a database:

 public async Task<SimpleObject> ExecuteAsync(int rowID, string value)
 {
    return await WriteToDB(int rowID, string value);
 }

So far so good. But, here's where I get lost:

 public async Task<SimpleObject> WriteToDB(int rowID, string value)
 {
      var dataRow = context. /// use linq to get a row with rowID
      dataRow.SomeColumn = value
      context.SaveChanges();
      var simpleObject = new SimpleObject();
      simpleObject.success = true;
      return simpleObject;
 }

 public class SimpleObject
 {
    public bool success {get;set;}
 }

I am very politely informed by VS that my method WriteToDB() lacks await and will run synchronously. I can still compile, and there won't be a runtime error. But, I can't figure out how to use await inside WriteToDB().

Upvotes: 4

Views: 295

Answers (3)

Stephen Cleary
Stephen Cleary

Reputation: 457362

I'll try and give a simple example.

As others have noted, the simple answer for the simple example is "use SaveChangesAsync instead of SaveChanges".

To answer the broader question of "how do I start using async", the best approach is:

  1. Identify naturally-asynchronous operations in your codebase. These are generally I/O operations. In this example, saving changes to the database.
  2. Change those APIs to use asynchronous APIs, and use await. In this example, change SaveChanges to await SaveChangesAsync.
  3. The compiler will inform you to change the containing method to use async, and it will also give you the correct return type to use. In this example, the compiler will instruct you to change SimpleObject WriteToDB(..) to async Task<SimpleObject> WriteToDBAsync(..).

Repeat steps (2) and (3) until your application compiles. In this example, step (2) will change the call return WriteToDB(int rowID, string value); to return await WriteToDBAsync(int rowID, string value); and step (3) will change SimpleObject Execute(..) to async Task<SimpleObject> ExecuteAsync(..).

It's much easier to apply async/await in this way, starting at the lowest levels and growing from there.

But at some point, won't there have to be a task that isn't async or won't await anything?

Yes. The lowest-level methods are generally implemented by TaskFactory.FromAsync or TaskCompletionSource<T>.

Upvotes: 1

YuvShap
YuvShap

Reputation: 3835

EntityFramework support async query and save operations such as SaveChangesAsync and ToListAsync, these async methods follow the "Task-based Asynchronous Pattern" and return Task or Task<T> that you can await.

You can rewrite your code to preform the querying and saving in an async way like this:

public async Task<SimpleObject> WriteToDB(int rowID, string value)
{
    var dataRow = await context.table.SingleAsync(item =>item.Id = /*some value*/);
    dataRow.SomeColumn = value
    await context.SaveChangesAsync();
    var simpleObject = new SimpleObject();
    simpleObject.success = true;
    return simpleObject;
}

Upvotes: 2

Ryan Bennett
Ryan Bennett

Reputation: 3432

You need to use the .SaveChangesAsync method.

 public async Task<SimpleObject> WriteToDB(int rowID, string value)
 {
      var dataRow = context. 
      dataRow.SomeColumn = value
      await context.SaveChangesAsync(); //change this line
      var simpleObject = new SimpleObject();
      simpleObject.success = true;
      return simpleObject;
 }

Upvotes: 3

Related Questions