web-dev-qa-db-fra.com

Pourquoi ne puis-je pas déboguer du code dans une méthode asynchrone?

En fait, j'ai commencé la nuit en essayant d'en savoir plus sur MongoDB, mais je suis en train de raccrocher et les choses en attente/async .NET. J'essaie d'implémenter le code affiché sur MongoDB site . J'ai dû le modifier un peu, pour pouvoir compiler mon programme. J'ai maintenant les éléments suivants dans mon application console:

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
}

Lorsque j'exécute l'application, le débogueur appelle ma méthode GetDataAsync() qui à son tour appelle la méthode GetData(). Il arrive à la ligne using (var cursor = await collection.FindAsync(filter)) puis revient immédiatement pour terminer la méthode main().

Tous les points d'arrêt que je mets en dessous de cette ligne sont ignorés, tout comme les points d'arrêt que je mets dans la méthode GetDataAsync(). Ce code n'est-il pas exécuté parce que le programme se ferme? Quelqu'un peut-il m'expliquer ce qui se passe?

25
Dave

Parce que vous n'attendez pas votre méthode GetDataAsync. Lorsque le premier await est atteint, le thread est renvoyé à l'appelant. Puisque vous n'attendez pas la fin de la tâche, votre application console se ferme et votre point d'arrêt n'est pas atteint. Vous devrez également mettre à jour la méthode GetDataAsync pour renvoyer un Task plutôt que void. Vous ne pouvez pas attendre le vide. Vous devez éviter d'utiliser async void pour autre chose que le gestionnaire d'événements.

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
}
34
Fabien PERRONNET