Be aware of “await” lacks CS1998

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

 

 

When working with “async” I figured out, that during refactoring process in development of components statistically “async” can often and implicitly happen. That means, that small changes in method signatures can cause changing of “async” behavior. Mostly developers should and aware of this, but such changes are mostly so silent, that unexpected behavioral changes might be often overseen.

Here one example, which might be harmful, but it can be very dangerous:

warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

What does this mean?

Assume you have following code:

   public async Task LoadDataAsync()
   {
    1.       
await this.ViewData.Dal.LoadDataAsync();

    2.        //NEXT STATEMENT
   }


If you see this warning on method ,LoadDataAsync() then the line 1 will be executed and immediately after this line the line 2 will be executed.
Assuming that the method LoadDataAsync() is a  long-running method,  it will likely ends up after executing of next statement in the line 2, before long running of the method is finished. However, note you have put await which is statement that says “Wait on LoadDataAsync() in line 1 to be executed and then execute next statement in line 2.”. Depending on what you are doing in statement 2, the application might possible bind to none existing data are even crash.

Following example shows a BAD implementation of the async method which will cause named warning.


       

public async Task LoadDataAsync()
        {
           
Task t = new Task(() =>
            {
               
// Some Long Running Code ..

            });

            t.Start();
        }

The BAD thing in this example is putting of async in front of Task. If you do this, without of having any await in the method, you will get warning CS1998. To prevent warning simply remove async . Unfortunately in the real life, you probably already implemented await inside of that method, but due same refactoring, you decided to implement awaiting code inside of  the task body and likely forgotten to remove async .

The CORRECT implementation of this method looks like:

       

public Task LoadDataAsync()
        {
           
Task t = new Task(() =>
            {
               
// Some Long Running Code ..

            });

            t.Start();

            return t;
        }

Another interesting article for async best practices: http://developers.de/blogs/damir_dobric/archive/2013/07/30/async-error-handling-recap.aspx

 


Posted Mar 04 2014, 07:38 PM by Damir Dobric
Filed under: , ,
developers.de is a .Net Community Blog powered by daenet GmbH.