当并行运行多个异步方法时,如何调试特定的异步方法?

时间:2016-08-05 07:28:03

标签: c# visual-studio-2015 async-await visual-studio-debugging

请看这个示例代码:

class Program
{
    private static readonly Random Random = new Random();

    static async Task TaskBody()
    {
        var counter = Random.Next(100);

        while (true)
        {
            counter += Random.Next(100);
            await Task.Delay(5000);
            Console.WriteLine($"Counter = {counter}");
        }
    }

    static void Main(string[] args)
    {
        for (var i = 0; i < 10; i++)
        {
            var _ = TaskBody();
        }

        Console.ReadLine();
    }
}

假设需要调试此代码(例如,while正文) 显而易见的方法是在某个地方点击断点:

enter image description here

但由于有10个并行运行的异步方法,调试器将停在每个方法。

如果只想调试特定方法怎么办?

最明显的是设置一些断点条件 这些事情被视为条件:

  • ThreaId。不适合异步方法,因为可以在await之后更改线程。
  • TaskId。可以(并将在此示例中)null
  • AsyncLocal<T>局部变量。 AsyncLocal<T>.Value不能在断点条件中使用,因为它会导致本机方法调用,并且不允许这样做。
  • TaskBody签名更改。例如,在调度时传递一些“Id”(在示例中最明显的方式是从调用方法传递i)。这将起作用,但仅需要进行不必要的更改以用于调试目的。
  • 另一个局部变量(例如Guid)为“方法ID”。这将起作用并且看起来是最好的选择,但仍然是诀窍。

我了解ThreadsTasksParallel Stacks调试窗口 事实上,在快速阅读this指南后会问这个问题。

只有使用VS2015功能才能在没有技巧和黑客的情况下实现这一目标吗?

1 个答案:

答案 0 :(得分:0)

我认为最简单的方法是使用类似Debug.WriteLine()的东西并输出你需要的东西,或者更好的是,将一些值传递给线程/任务,(某种ID),然后设置一个条件断点,ID == Thread#

e.g。你用1-10的ID开始你的线程,你想调试线程#5

ID为== 5

的条件断点

我希望这有效:)

编辑:我认为后者是你在问题中所说的,但我认为这是最好的解决方案,除非你有很多线程,否则ThreadID不应该受到伤害。