2016-04-20 19 views
12

In realtà ho iniziato la serata cercando di saperne di più su MongoDB, ma mi sto facendo impazzire e il .NET attende/async. Sto cercando di implementare il codice mostrato su site di MongoDB. Ho dovuto modificarlo un po ', così ho potuto compilare il mio programma. So che ho la seguente applicazione per la mia console.Perché non riesco a eseguire il debug del codice in un metodo asincrono?

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 
    } 

Quando eseguo l'applicazione, il debugger chiamerà nel mio metodo GetDataAsync(), che a sua volta chiama al metodo GetData(). Raggiunge la linea "usando (var cursor = attende collection.FindAsync (filter))" e poi ritorna immediatamente per finire il metodo main().

Tutti i punti di interruzione che inserisco sotto quella linea vengono ignorati, così come tutti i punti di interruzione che ho inserito nel metodo GetDataAsync(). Questo codice non viene eseguito perché il programma termina? Qualcuno può spiegarmi cosa sta succedendo?

risposta

16

Perché non stai aspettando il tuo metodo GetDataAsync. Quando viene raggiunto il primo await, il thread viene restituito al chiamante. Dal momento che non si è in attesa del completamento dell'attività, l'uscita dell'applicazione console e il punto di interruzione non vengono raggiunti. Sarà inoltre necessario aggiornare il metodo GetDataAsync per restituire un valore Task anziché vuoto. Non puoi aspettare il nulla. Si consiglia di avoid using async void per qualcosa di diverso dal gestore di eventi.

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 
} 
+0

Ho provato, ma ho appena finito con un errore di compilazione di "Operatore". non può essere applicato all'operando di tipo "void" " – Dave

+0

Ho aggiornato la mia risposta, dovrebbe essere ok :) –

+0

Grande! sta funzionando ora. Grazie per l'aiuto! – Dave