2016-04-20 15 views
12

Właściwie to zacząłem noc próbując dowiedzieć się więcej o MongoDB, ale zaczynam się rozłączać, a .NET czeka na/asynch. Próbuję zaimplementować kod pokazany na MongoDB's site. Musiałem go trochę zmodyfikować, aby program mógł się skompilować. Wiem, że mam następującą aplikację konsoli.Dlaczego nie mogę debugować kodu w metodzie asynchronicznej?

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 
    } 

Kiedy uruchomić aplikację, debugger będzie zadzwonić do mojego sposobu GetDataAsync(), która z kolei powołuje do metody GetData(). Przechodzi do linii "za pomocą (var cursor = czekaj na collection.FindAsync (filter))", a następnie natychmiast wraca, aby zakończyć metodę main().

Wszelkie punkty przerwania, które umieszczam poniżej tego wiersza, są ignorowane, podobnie jak wszelkie punkty przerwania, które umieszczam w metodzie GetDataAsync(). Czy ten kod po prostu nie uruchamia się, ponieważ program wychodzi? Czy ktoś może mi wyjaśnić, co się dzieje?

Odpowiedz

16

Ponieważ nie czekasz na swoją metodę GetDataAsync. Po osiągnięciu pierwszego numeru await wątek jest zwracany do osoby dzwoniącej. Ponieważ nie oczekujesz na zakończenie zadania, wyjście aplikacji konsoli i punkt przerwania nie zostaną osiągnięte. Będziesz również musiał zaktualizować metodę GetDataAsync, aby zamiast niej zwracać wartość Task. Nie możesz czekać na pustkę. Powinieneś avoid using async void dla czegokolwiek innego niż obsługa zdarzeń.

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

Próbowałem, ale ja po prostu skończyć z błędem kompilacji z „operator". nie można zastosować do argumentu typu "void" " – Dave

+0

Zaktualizowałem odpowiedź, powinno być dobrze :) –

+0

Świetnie! już działa. Dzięki za pomoc! – Dave