我如何在Visual Studio中将多线程应用程序调试为单线程

时间:2014-02-06 14:29:08

标签: c# multithreading visual-studio

如果我想按任务调试任务,我该怎么办?

static void Main()
{
    var numbers = Enumerable.Range(0, 10);
    var tasks = new List<Task>();
    foreach (var number in numbers)
    {
        var task = Task.Factory.StartNew(n =>
            {
                var data = LongLoadOperation(n);           // 1.
                var calculation = Calculate(data);         // 2.
                var result = BuildNiceResult(calculation); // 3.
                return result;
            }, number);
            tasks.Add(task);
    }
    Task.WaitAll(tasks.ToArray());
    Console.WriteLine("Done");
}

我不想从任务切换到任务。调试此代码并不是很舒服。

3 个答案:

答案 0 :(得分:0)

如果你在一个任务中放置一个断点,那么它将被命中,就像你有任务一样。因此,您可以一次调试每个任务,但由于您处于多线程环境中,请注意,如果您在线程上停止,其他人将继续运行,除非您也停止/暂停它们。

一系列断点应该允许您在应用程序中创建检查点。

答案 1 :(得分:0)

首先,您无法确定线程执行的顺序。您可能有完全不同的订单。

尽管如此,如果要调试多线程应用程序,可以通过在Debug-&gt; Windows-&gt; Threads中选择它来选择特定线程。

如果您使用控制台.Writeline的内联语法,您将看不到它在那里。您可以为此介绍一种方法:

{
//...
    var task = Task.Factory.StartNew(() => MyMethod(number));`.
//...
}

private void MyMethod(int number)
{
    Console.WriteLine(number);
}

顺便说一句,您可以使用Parallel.Foreach来真正缩短代码(我假设您在代码中使用的内容与Console.WriteLine不同。):

var numbers = Enumerable.Range(0, 10);
Parallel.ForEach(numbers, Console.WriteLine);
Console.WriteLine("Done");

如果您只想调试处理特定号码的线程,您可以设置一个断点条件:只有当该号码符合该条件时,您的断点才会被触发。

答案 2 :(得分:0)

很惊讶没人提到这个......但是也许你应该看一下“Threads”窗口或“Parallel Tasks”窗口(在Debug - &gt; Windows中找到)。这些可能有助于调试多线程代码。如果您想逐个介入每个任务,请在任务开头设置断点。每当您在每个任务上点击该断点时,请转到其中一个窗口,右键单击正在执行的线程/任务,然后选择“冻结”它的选项。这将阻止线程自行执行。您可以使用“线程/并行任务”窗口在当前正在执行/冻结的各种任务之间切换。如果您想完成其中一项任务,只要您准备好就可以“解冻”它。您实际上可以使用这些窗口重新创建一些罕见的竞争条件场景。