首先说明:如果没有进入调试模式的话,默认的调试窗口如下:
开始前的准备:
新建控制台程序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调用的。
其他窗口比较常用,就不介绍了,是不是有一些你没用到的窗口呢?
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!
网友评论