为什么我不能在异步方法中调试代码?

时间:2016-04-20 03:22:08

标签: c# mongodb asynchronous

我实际上是在晚上尝试了解有关MongoDB的更多内容,但是我已经挂断了.NET等待/异步的东西。我正在尝试实现MongoDB site上显示的代码。我不得不稍微修改它,所以我可以让我的程序编译。我知道有以下我的控制台应用程序。

    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()方法。它使用(var cursor = await collection.FindAsync(filter))&#34;然后立即返回以完成main()方法。

我放在该行下面的任何断点都被忽略,就像我在GetDataAsync()方法中放置的任何断点一样。此代码是否因为程序退出而无法运行?有人可以向我解释发生了什么事吗?

3 个答案:

答案 0 :(得分:32)

因为您没有等待GetDataAsync方法。到达第一个await时,线程将返回给调用者。由于您没有等待任务完成,因此未达到控制台应用程序退出和断点。您还需要更新GetDataAsync方法以返回Task而不是无效。你不能等待无效。除了事件处理程序之外,你应该avoid using 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
}

答案 1 :(得分:3)

我对异步开发不是很好,并且遇到了类似的问题,但是我在Main中启动了异步方法,例如:

Task.Run(async () => await GetDataAsync());

我认为垃圾收集器正在处理匿名方法,因为不再有任何引用。使用Fabien的.Wait()使我可以逐步完成程序并进行调试。我正在将netcore 2.1与vs2017一起使用

答案 2 :(得分:0)

Visual Studio 更新后,处理调试模式变得更加一致。如果还没有,最好尽快更新。

希望这篇文章能帮到你

https://devblogs.microsoft.com/visualstudio/how-do-i-debug-async-code-in-visual-studio/