【问题标题】:Why can't I debug code in an async method?为什么我不能在异步方法中调试代码?
【发布时间】:2016-04-20 03:22:07
【问题描述】:

我实际上是在晚上开始尝试了解有关 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() 方法。它到达using (var cursor = await collection.FindAsync(filter)) 行,然后立即返回以完成main() 方法。

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

【问题讨论】:

标签: c# mongodb asynchronous


【解决方案1】:

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

【讨论】:

  • 我试过了,但我最终得到了“操作员”的编译错误。不能应用于“void”类型的操作数”
  • 完美地描述了为什么断点没有到达。
  • c# 中的 web 应用程序陷入死锁。
【解决方案2】:

我对 async dev 不太擅长并且遇到了类似的问题,但是我在 Main 中启动了 async 方法,例如:

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

我认为垃圾收集器正在处理匿名方法,因为没有任何东西可以引用它。使用 Fabien 的 .Wait() 让我可以逐步完成程序并进行调试。我正在使用带有 vs2017 的 netcore 2.1

【讨论】:

  • The expression cannot be evaluated. A new instance of System.Threading.Tasks.Task cannot be created while under a debugger. 出错:(
猜你喜欢
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 2023-03-12
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
相关资源
最近更新 更多