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

2019-02-05 20:46发布

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 know have the following 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?

1条回答
女痞
2楼-- · 2019-02-05 20:50

Because your are not waiting your GetDataAsync method. When the first await is reached the thread is returned to the caller. Since your not waiting for the completion of the task, your console application exit 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 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
}
查看更多
登录 后发表回答