C#中一些你可能沒用過的調試視窗的方法

來源:互聯網
上載者:User

首先說明:如果沒有進入偵錯模式的話,預設的調試視窗如下:

開始前的準備:

建立控制台程式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調用的。

其他視窗比較常用,就不介紹了,是不是有一些你沒用到的視窗呢?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.