Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I debug code in an async method?

I actually started the night trying to learn more about MongoDB, but am getting hung up and the .NET await/async stuff. I am trying to implement the code shown on MongoDB's site. I've had to modify it a tad bit, so I could get my program to compile. I now have the following in my console application:

protected static IMongoClient _client; protected static IMongoDatabase _database;  static void Main(string[] args) {     _client = new MongoClient();     _database = _client.GetDatabase("test");      GetDataAsync(); }  private static async void GetDataAsync() //method added by me. {     int x = await GetData(); }  private static async Task<int> GetData() {     var collection = _database.GetCollection<BsonDocument>("restaurants");     var filter = new BsonDocument();     var count = 0;     Func<int> task = () => count; //added by me.     var result = new Task<int>(task); //added by me.     using (var cursor = await collection.FindAsync(filter)) //Debugger immediately exits here, goes back to main() and then terminates.      {         while (await cursor.MoveNextAsync())         {             var batch = cursor.Current;             foreach (var document in batch)             {                 // process document                 count++;             }         }     }      return count; //added by me } 

When I run the application, the debugger will call into my GetDataAsync() method which in turn calls into the GetData() method. It gets to the line using (var cursor = await collection.FindAsync(filter)) and then immediately returns to finish the main() method.

Any break points I put below that line are ignored, as are any breakpoints I put in the GetDataAsync() method. Is this code just not getting run because the program exits? Can someone explain to me what is going on?

like image 831
Dave Avatar asked Apr 20 '16 03:04

Dave


People also ask

How do I debug async code in Visual Studio?

Double-clicking an active or awaiting task shows the async call stack in the Call Stack window. To understand which thread is running a specific task, you can swap between the Parallel Threads and Parallel Tasks windows. You can do this by right-clicking and selecting Go To Thread in the context menu.

What happens if we execute an asynchronous method but don't await it?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.

Can async method have out parameter?

You can't have async methods with ref or out parameters.


2 Answers

Because you are not awaiting your GetDataAsync method. When the first await is reached the thread is returned to the caller. Since you are not waiting for the completion of the task, your console application exits and your breakpoint is not reached. You will also need to update the GetDataAsync method to return a Task rather than void. You cannot await void. You should avoid using async void for anything other than the event handler.

protected static IMongoClient _client; protected static IMongoDatabase _database;  static void Main(string[] args) {     _client = new MongoClient();     _database = _client.GetDatabase("test");      GetDataAsync().Wait();      // Will block the calling thread but you don't have any other solution in a console application }  private static async Task GetDataAsync() //method added by me. {     int x = await GetData(); }  private static async Task<int> GetData() {     var collection = _database.GetCollection<BsonDocument>("restaurants");     var filter = new BsonDocument();     var count = 0;     Func<int> task = () => count; //added by me.     var result = new Task<int>(task); //added by me.     using (var cursor = await collection.FindAsync(filter)) //Debugger immediately exits here, goes back to main() and then terminates.      {         while (await cursor.MoveNextAsync())         {             var batch = cursor.Current;             foreach (var document in batch)             {                 // process document                 count++;             }         }     }      return count; //added by me } 
like image 161
Fabien ESCOFFIER Avatar answered Sep 28 '22 04:09

Fabien ESCOFFIER


I' not so good with async dev and had a similar problem, however I was kicking off the async method in Main like:

Task.Run(async () => await GetDataAsync()); 

I think the Garbage Collector was disposing of the anonymous method as nothing had a reference to it anymore. Using Fabien's .Wait() allowed me to step through the program and debug. I am using netcore 2.1 with vs2017

like image 39
Luke Avatar answered Sep 28 '22 04:09

Luke