C#中一些你可能没用过的调试窗口的方法

首先说明:如果没有进入调试模式的话,默认的调试窗口如下:

开始前的准备:

新建控制台程序DebugWindowDemo:

修改Program.cs 的代码为:


代码如下:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;

class S
    {
       public static void Main()
        {
            pcount = Environment.ProcessorCount;
            Console.WriteLine("Proc count = " + pcount);
            ThreadPool.SetMinThreads(4, -1);
            ThreadPool.SetMaxThreads(4, -1);

t1 = new Task(A, 1);
            t2 = new Task(A, 2);
            t3 = new Task(A, 3);
            t4 = new Task(A, 4);
            Console.WriteLine("Starting t1 " + t1.Id.ToString());
            t1.Start();
            Console.WriteLine("Starting t2 " + t2.Id.ToString());
            t2.Start();
            Console.WriteLine("Starting t3 " + t3.Id.ToString());
            t3.Start();
            Console.WriteLine("Starting t4 " + t4.Id.ToString());
            t4.Start();

Console.ReadLine();
        }

static void A(object o)
        {
            B(o);
        }
        static void B(object o)
        {
            C(o);
        }
        static void C(object o)
        {
            int temp = (int)o;

Interlocked.Increment(ref aa);
            while (aa < 4)
            {

}

if (temp == 1)
            {
                // BP1 - all tasks in C

Debugger.Break();
                waitFor1 = false;
            }
            else
            {
                while (waitFor1)
                {

}
            }
            switch (temp)
            {
                case 1:
                    D(o);
                    break;
                case 2:
                    F(o);
                    break;
                case 3:
                case 4:
                    I(o);
                    break;
                default:
                    Debug.Assert(false, "fool");
                    break;
            }
        }
        static void D(object o)
        {
            E(o);
        }
        static void E(object o)
        {
            // break here at the same time as H and K

while (bb < 2)
            {

}
            //BP2 - 1 in E, 2 in H, 3 in J, 4 in K

Debugger.Break();
            Interlocked.Increment(ref bb);

//after

L(o);
        }
        static void F(object o)
        {
            G(o);
        }
        static void G(object o)
        {
            H(o);
        }
        static void H(object o)
        {
            // break here at the same time as E and K

Interlocked.Increment(ref bb);
            Monitor.Enter(mylock);
            while (bb < 3)
            {

}
            Monitor.Exit(mylock);

//after

L(o);
        }
        static void I(object o)
        {
            J(o);
        }
        static void J(object o)
        {
            int temp2 = (int)o;

switch (temp2)
            {
                case 3:
                    t4.Wait();
                    break;
                case 4:
                    K(o);
                    break;
                default:
                    Debug.Assert(false, "fool2");
                    break;
            }
        }
        static void K(object o)
        {
            // break here at the same time as E and H

Interlocked.Increment(ref bb);
            Monitor.Enter(mylock);
            while (bb < 3)
            {

}
            Monitor.Exit(mylock);

//after

L(o);
        }
        static void L(object oo)
        {
            int temp3 = (int)oo;

switch (temp3)
            {
                case 1:
                    M(oo);
                    break;
                case 2:
                    N(oo);
                    break;
                case 4:
                    O(oo);
                    break;
                default:
                    Debug.Assert(false, "fool3");
                    break;
            }
        }
        static void M(object o)
        {
            // breaks here at the same time as N and Q

Interlocked.Increment(ref cc);
            while (cc < 3)
            {

}
            //BP3 - 1 in M, 2 in N, 3 still in J, 4 in O, 5 in Q

Debugger.Break();
            Interlocked.Increment(ref cc);
            while (true)
                Thread.Sleep(500); // for ever

}
        static void N(object o)
        {
            // breaks here at the same time as M and Q

Interlocked.Increment(ref cc);
            while (cc < 4)
            {

}
            R(o);
        }
        static void O(object o)
        {
            Task t5 = Task.Factory.StartNew(P, TaskCreationOptions.AttachedToParent);
            t5.Wait();
            R(o);
        }
        static void P()
        {
            Console.WriteLine("t5 runs " + Task.CurrentId.ToString());
            Q();
        }
        static void Q()
        {
            // breaks here at the same time as N and M

Interlocked.Increment(ref cc);
            while (cc < 4)
            {

}
            // task 5 dies here freeing task 4 (its parent)

Console.WriteLine("t5 dies " + Task.CurrentId.ToString());
            waitFor5 = false;
        }
        static void R(object o)
        {
            if ((int)o == 2)
            {
                //wait for task5 to die

while (waitFor5) { ;}

int i;
                //spin up all procs

for (i = 0; i < pcount - 4; i++)
                {
                    Task t = Task.Factory.StartNew(() => { while (true);});
                    Console.WriteLine("Started task " + t.Id.ToString());
                }

Task.Factory.StartNew(T, i + 1 + 5, TaskCreationOptions.AttachedToParent); //scheduled

Task.Factory.StartNew(T, i + 2 + 5, TaskCreationOptions.AttachedToParent); //scheduled

Task.Factory.StartNew(T, i + 3 + 5, TaskCreationOptions.AttachedToParent); //scheduled

Task.Factory.StartNew(T, i + 4 + 5, TaskCreationOptions.AttachedToParent); //scheduled

Task.Factory.StartNew(T, (i + 5 + 5).ToString(), TaskCreationOptions.AttachedToParent); //scheduled

//BP4 - 1 in M, 2 in R, 3 in J, 4 in R, 5 died

Debugger.Break();
            }
            else
            {
                Debug.Assert((int)o == 4);
                t3.Wait();
            }
        }
        static void T(object o)
        {
            Console.WriteLine("Scheduled run " + Task.CurrentId.ToString());
        }
        static Task t1, t2, t3, t4;
        static int aa = 0;
        static int bb = 0;
        static int cc = 0;
        static bool waitFor1 = true;
        static bool waitFor5 = true;
        static int pcount;
        static S mylock = new S();
    }

按F5,开始运行:

由于Debugger.Break();

所以当执行到这里的时候,Debugger会中断。

这个时候再看看调试窗口会发现多了几个窗口:

点击调试->窗口->并行任务,界面如下:

按下F5,继续运行:

双击查看相应等待的任务,就可以知道这个工作线程为什么等待了。

例如:

继续按F5,运行,你应该会看到:

总之关于当前运行的并行任务你都可以看的到。

关闭程序,重新F5,进入调试模式

选择调试->窗口->并行堆栈

可以看到:

其中蓝线代表当前正在执行的线程。

如果右键点击方法视图的S.C ,可以看到右键菜单如下:

点击切换方法视图

可以看到:

关闭程序,重新F5,进入调试模式

点击调试->窗口->线程:

可以看到:

当前控制台的所有线程都在这里。

在线程上点击右键可以冻结线程:


冻结线程也就是Pause线程,

冻结的线程可以被解冻,也就是Resume。

其他的窗口:

调试->窗口->模块:可以看到当前程序加载的所有模块。


调试->窗口->进程:


调试->窗口->反汇编:


调试->窗口->寄存器:


调试->窗口->调用堆栈:

调用堆栈窗口是比较常用的窗口:


上图表示先调用A方法,接着B方法,接着C方法。

也可以认为是C方法是B调用,而B方法是A调用的。

其他窗口比较常用,就不介绍了,是不是有一些你没用到的窗口呢?

(0)

相关推荐

  • 在ASP.NET 2.0中操作数据之七十一:保护连接字符串及其它设置信息

    导言: ASP.NET应用程序的设置信息通常都存储在一个名为Web.config的XML文件里.在教程的前面部分我们已经好几次修改过Web.config文件了.比如在第一章,我们创建名为Northwind的数据集时,数据库连接字符串信息自动的添加到Web.config文件的<connectionStrings>节点.再后来,在第3章里,我们手动更新了Web.config文件,添加了一个<pages>元素,对所有的ASP.NET页面运用DataWebControls主题. 由于Web

  • ASP.NET笔记之页面跳转、调试、form表单、viewstate、cookie的使用说明

    1.页面跳转: (1 服务器传输 server.Transer(http://www.jb51.net);在定向到新页面后,还是会显示原来的URL,浏览器返回不会退回到原页面,历史记录也不会记录. 应用于完整的控制传输,例如安装向导. (2 超链接 (3 浏览器重定向 Redirect ,速度快,没有发送到服务器 (4 跨页发送 PostBackUrl="http://www.jb51.net" /> IsCrossPagePostBack用来判断是否为跨页提交 IsPostBa

  • 在ASP.NET 2.0中操作数据之六十八:为DataTable添加额外的列

    导言: 当向类型化的数据集(Typed DataSet)添加一个TableAdapter时,相应的DataTable的构架已经由TableAdapter的主查询定义好了.比如,如果主查询返回A, B,C这3个域,那么 DataTable将有对应的3个列A, B,和C.除了主查询以外,TableAdapter还可以包含其他的查询,可能是返回基于某些参数的数据.比如,ProductsTableAdapter的主查询返回所有产品的信息,此外,ProductsTableAdapter还包含诸如GetPr

  • 在ASP.NET 2.0中操作数据之六十九:处理Computed Columns列

    导言: Microsoft SQL Server里有一种computed columns列.这种列的值是通过一个表达式来计算,而表达式引用的是同一张表的其它列的值.打个比方,有一张ServiceLog表,其包含了ServicePerformed, EmployeeID, Rate, Duration等列. 虽然我们可以在一个web页面或其它什么界面里计算每笔服务的费用(也就是 比率 rate乘以时间段duration),不过我们也可以手动向ServiceLog表添加一个 AmountDue列以反

  • C# 动态编译、动态执行、动态调试

    在此基础上我做了一些封装,为使调用更加简单,并增加了对动态代码调试的支持,相同代码只编译一次的支持,代码改动自动重新编译,代码引用文件的自动加载和手工加载等功能. 如上图,我封装的类CSharpProvider很简单,下面说明一下一些公共成员的用法. 公共属性 AssemblyFileName:这个属性指定动态编译后生成的配件名称. CompilerParameters:这个属性指定编译的参数 References:这个属性指定被编译代码中的引用.调用者只要调用References.Add("x

  • 在ASP.NET 2.0中操作数据之七十:配置数据库连接和命令等级设置

    导言: 在本系列我们用类型化的DataSets来构建数据访问层.就像在第一章探讨的那样,类型化DataSets的DataTables用作存储数据的"仓库",而TableAdapters作为连接数据库的通道,以检索.修改数据.TableAdapters 将处理数据库的很多复杂的细节进行了封装,将我们解脱出来,免去了写代码连接数据库.发出命名.向DataTable填充数据的痛苦. 不过在某些时候我们需要深入的探究TableAdapter,直接写代码处理ADO.NET对象.在第61章<

  • 在ASP.NET 2.0中操作数据之七十二:调试存储过程

    导言: Visual Studio有很多的调试功能.我们只需要稍稍点点鼠标,敲敲键盘就可以使用断点(breakpoints)来打断某个程序的执行,并查看其状态.除了调试代码以外,Visual Studio也支持对SQL Server里面的存储过程进行调试.就像可以在ASP.NET页面的后台代码类或Business Logic Layer class类里设置断点一样,我们也可以在存储过程里设置断点. 本文我们将考察如何在Visual Studio的Server Explorer里进入存储过程并设置

  • 调试ASP.NET2005/2008时,端口不正确的解决三套方案

    在VS2008里点"调试"后.ASP.NET Development Server的端口比调试时打开的浏览器上的端口要大2,造成每次需要调试都要手动改浏览器的端口号.如下图: 解决方法一:为 ASP.NET Development Server 指定端口 1.在解决方案资源管理器中,单击应用程序的名称. 2.在"属性"窗格中,单击"使用动态端口"旁的下箭头,然后从下拉列表选择"False".    这会允许对"端口号

  • 调试ASP.NET应用程序的方法和技巧

    以前使用ASP开发过Web应用程序的人员肯定知道调试Web应用程序是多么麻烦.在ASP中,调试是痛苦的,通常包括了使用Response.Write()方法输出变量的值.那么请问一下自己:你有多少次忘记了在布署应用程序之前删除了调试语句? 随着.NET框架组件的出现这种情况发生了彻底的改变.在.NET中,你可以使用Visual Studio .NET中的调试程序跟踪整个Web应用程序的执行,或者使用System.Web.TraceContext名字空间中的Trace类.本文演示如何使用Trace类

  • asp.net程序编译调试时偶尔出现访问被拒绝的错误的解决方法

    问题描述: 编写asp.net程序,当编译调试比较频繁的时候,很容易经常地出现访问被拒绝.形如: 分析器错误信息: 访问被拒绝:"Microsoft.Web.UI.WebControls".源错误: 行 197: <add assembly="System.Web.Mobile, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>行 198: <add as

  • Asp.net调试的一些问题小结

    昨天到今天搞了一整天,把人都要差点搞崩了! ,以后再也不能乱关机了,因为这次的大意,几乎所有的Net安装,调试问题都被我碰到了,还好,我一个个把他记录下来了,同时,在CSDN找了一些相关的解决方法,不敢独享,供大家相互学习交流之用. 起因是这样的,机子运行IE时假死,我用着不爽,就二话不说热启动,结果就出事了. 重新打开正在Vs2003.Net里面正在作的项目时,老半天没反应,机子变得异常慢,当然,出于职业的敏感,马上来了个Ctrl+Alt+Del,这下不好,CPU占用100%,一直高居不下,运

随机推荐