Почему я не могу отлаживать код методом async?

Я фактически начал ночь, пытаясь узнать больше о MongoDB, но я зацикливался на вещах .NET await/async. Я пытаюсь реализовать код, показанный на MongoDB сайте. Мне пришлось немного его изменить, чтобы я мог заставить мою программу компилироваться. Теперь у меня в консоли есть следующее:

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
}

Когда я запускаю приложение, отладчик вызывает мой метод GetDataAsync(), который, в свою очередь, вызывает метод GetData(). Он попадает в строку using (var cursor = await collection.FindAsync(filter)), а затем сразу же возвращается, чтобы завершить метод main().

Любые точки останова, которые я ставлю ниже этой линии, игнорируются, как и любые точки останова, которые я ставлю в методе GetDataAsync(). Этот код просто не запускается из-за выхода из программы? Может кто-нибудь объяснить мне, что происходит?

Ответ 1

Потому что вы не ожидаете своего метода GetDataAsync. Когда достигается первый await, поток возвращается вызывающему. Так как вы не дожидаетесь завершения задачи, выход вашего консольного приложения и ваша точка останова не достигнуты. Вам также потребуется обновить метод GetDataAsync, чтобы вернуть Task вместо void. Вы не можете ждать пустоты. Вы должны избегать использования async void для чего-либо, кроме обработчика событий.

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
}