iT邦幫忙

2026 iThome 鐵人賽

DAY 23
0
佛心分享-IT 人自學之術

學過一點 React,卻被撈進 C#:新手用 AI 硬啃 MVC 企業專案的 3 個月實錄系列 第 23

Day 23|程式到底有沒有跑到這裡?用中斷點追執行流程

  • 分享至 

  • xImage
  •  

上一篇學會用 F12 之後,我終於可以從:

Controller
↓
Service
↓
Repository / DBService
↓
Database

一路追到真正的程式碼。

但很快又遇到另一個問題。

我找到這個方法了。

可是它「寫在這裡」
不代表程式執行時真的有跑到這裡吧?

尤其改企業專案時,很常發生這種情況:

我明明改了這段程式
↓
重新操作畫面
↓
完全沒反應

這時候我以前第一個反應可能是:

是不是我程式寫錯?
是不是瀏覽器快取?
是不是專案沒重新 Build?

但其實還有一個很基本的問題應該先確認:

這次操作,
到底有沒有執行到我改的這段程式?

這時就要用:

Breakpoint
中斷點

中斷點(Breakpoint)是什麼?

中斷點可以先理解成:

我在程式碼某一行放一個「暫停點」,程式執行到這裡時先停下來給我看。

例如 Controller:

public IActionResult Detail(int id)
{
    var model = _userService.GetDetail(id);

    return View(model);
}

如果我想確認:

開啟詳細資料頁時
到底有沒有進到 Detail()

就可以在:

var model = _userService.GetDetail(id);

這一行下中斷點:

https://ithelp.ithome.com.tw/upload/images/20260813/20181499rMMOZ5WVFZ.png

接著執行程式,再去瀏覽器操作詳細資料頁。

如果 Visual Studio 停在這一行:

代表真的有執行到這裡

如果完全沒有停:

那我就要重新確認自己是不是找錯 Controller、Action 或流程了

怎麼下中斷點?

最直覺的方法就是:

點程式碼左邊的灰色區域

例如:

public IActionResult Detail(int id)
{
    var model = _userService.GetDetail(id);
    return View(model);
}

在:

var model = _userService.GetDetail(id);

左邊點一下。

就會出現一個紅色圓點。

代表:

這一行有 Breakpoint

再點一次,就可以取消。

也可以把游標放在那一行,按:

F9

來新增或移除中斷點。

所以可以先記:

F9
新增 / 移除 Breakpoint

下了中斷點,為什麼還沒有停?

因為只有放中斷點還不夠。

程式必須在:

Debug 模式

https://ithelp.ithome.com.tw/upload/images/20260813/2018149934V31wP9MV.png

這裡執行

Visual Studio 裡通常可以按:

F5

也就是:

Start Debugging
開始偵錯

流程就是:

第一步
找到想確認的程式

↓

第二步
下 Breakpoint

↓

第三步
按 F5 啟動 Debug

↓

第四步
到瀏覽器操作功能

↓

第五步
如果程式跑到那一行
Visual Studio 就會停下來

實際來追一次 Controller

假設網址是:

/User/Detail/10

Controller:

public IActionResult Detail(int id)
{
    var model = _userService.GetDetail(id);

    return View(model);
}

我想確認這個網址是不是真的進:

Detail(int id)

就可以在第一行:

var model = _userService.GetDetail(id);

下中斷點。

接著:

F5
↓
開啟網站
↓
進入 /User/Detail/10

如果 Visual Studio 跳回來,並停在這一行:

var model = _userService.GetDetail(id);

就可以先確認:

/User/Detail/10

真的有進到:

UserController.Detail()

這比單純看網址猜測可靠很多。

程式停下來的時候代表什麼?

Visual Studio 停在某一行時,通常會看到黃色標示。

這時要注意:

黃色那一行
通常代表「接下來準備執行的程式」

例如停在:

var model = _userService.GetDetail(id);

代表這一行目前準備要執行。

不是代表:

這一行已經執行完了

這個差別很重要。

因為如果我現在想看:

model 裡面有什麼

但:

_userService.GetDetail(id)

還沒執行完。

model 當然可能還沒有我想看的資料。

這時候就要讓程式往下一步跑。

F10:執行下一行,但不要跑進方法裡

程式停下來之後,我最常用的是:

F10

它叫:

Step Over
逐程序

例如目前停在:

var model = _userService.GetDetail(id);

按 F10。

Visual Studio 會:

執行完這一行
↓
停在下一行

變成:

var model = _userService.GetDetail(id);

return View(model);

這時候:

GetDetail(id)

已經執行完成。

所以現在就可以查看:

model 到底拿到什麼資料

簡單記:

F10
執行這一行
但不要進去看方法內部

F11:我想進去看這個方法到底做了什麼

假設目前停在:

var model = _userService.GetDetail(id);

而我現在不是只想得到結果。

我想知道:

GetDetail()
裡面到底做了什麼?

這時就可以按:

F11

也就是:

Step Into
逐陳述式

按下去後,可能直接進到:

public UserDetailViewModel GetDetail(int id)
{
    var user = _userRepository.GetById(id);

    ...
}

所以:

F10
我只想執行完這個方法

F11
我要進這個方法裡面看

這兩個我一開始超容易搞混。

後來就記成:

F10
跨過去

F11
鑽進去

F5:繼續執行

假設我已經看完這裡,不想每一行慢慢跑。

就可以再按:

F5

這時程式會繼續正常執行。

直到:

遇到下一個 Breakpoint

才會再次停下來。

所以 Debug 時我現在最常用的是:

F5
繼續跑

F10 跨過去
跑下一行,不進方法

F11 鑽進去
跑進方法裡

F9
新增 / 移除中斷點

用中斷點一路從 Controller 追到 Service

上一篇我們用 F12 看的是:

程式碼「寫在哪」

現在 Breakpoint 看的是:

程式「實際怎麼跑」

例如:

public IActionResult Detail(int id)
{
    var model = _userService.GetDetail(id);

    return View(model);
}

先在:

var model = _userService.GetDetail(id);

停住。

接著按:

F11 鑽進去看

可能進到 Service:

public UserDetailViewModel GetDetail(int id)
{
    var user = _userRepository.GetById(id);

    var model = new UserDetailViewModel
    {
        Name = user.Name,
        Email = user.Email
    };

    return model;
}

再停在:

var user = _userRepository.GetById(id);

如果我又想知道:

Repository 查了什麼?

再按:

F11 鑽進去看

可能進到:

public User GetById(int id)
{
    return _dbContext.Users
        .FirstOrDefault(x => x.Id == id);
}

這樣我就真的可以看著程式跑:

Controller
↓
Service
↓
Repository
↓
Database 查詢

跟上一篇只用 F12 靜態看程式相比,感覺完全不一樣。

F12 和 中斷電(Breakpoint) 到底差在哪?

兩者比較後會更清楚!

F12

回答:

這個方法寫在哪裡?

例如:

_userService.GetDetail(id)
↓
F12
↓
找到 GetDetail() 定義

但是:

你找到它
不代表這次程式真的有執行它

Breakpoint

回答:

這次執行真的有跑到這裡嗎?

所以我現在會這樣搭配:

不知道程式在哪
↓
F12

知道程式在哪
但不知道有沒有跑到
↓
中斷點 Breakpoint

這兩個一起用,追企業專案真的差很多。

為什麼我的中斷點沒有停?

這也是實際上很常遇到的。

如果中斷點完全沒有被打到,我現在不會立刻覺得:

Visual Studio 壞掉了

我會先一個一個確認。

第一個:這個功能真的有執行到這個 Action 嗎?

例如我以為按下:

儲存

會跑:

Edit()

但實際上可能跑的是:

Update()

或另一支 API。

這時中斷點當然不會停。

所以先確認:

網址
Route
HTTP Method
Controller
Action

有沒有找對。

第二個:GET 和 POST 有沒有看錯?

這個也很常見。

例如 Controller:

[HttpGet]
public IActionResult Edit(int id)
{
    return View();
}

下面又有:

[HttpPost]
public IActionResult Edit(EditUserViewModel model)
{
    ...
}

兩個方法都叫:

Edit

但是:

第一次打開頁面
↓
GET Edit

按下儲存
↓
POST Edit

如果我把中斷點下在:

GET Edit

然後一直按儲存,當然可能不會停在我要看的位置。

所以看到同名 Action 時,要特別注意:

[HttpGet]

和:

[HttpPost]

第三個:我是不是沒有用 Debug 模式啟動?

如果只是一般執行,而不是:

Start Debugging

中斷點就可能無法按照預期工作。

最基本先確認:

是不是按 F5 啟動偵錯

而不是只看網站有沒有開起來。

第四個:中斷點是不是空心的?

正常能使用的中斷點通常會顯示紅色實心圓點。

但有時可能看到:

空心的中斷點

或 Visual Studio 提示:

The breakpoint will not currently be hit

這通常代表:

目前執行的程式
和這份原始碼沒有正確對應上

可能的原因很多,例如:

程式沒有重新 Build
目前跑的不是這個專案
目前載入的是另一個版本
Debug symbols 沒有載入

這時就不是一直重新整理瀏覽器可以解決。

要先確認:

我現在 Debug 的到底是不是這份程式?

這在多專案的 Solution 裡尤其重要。

第五個:這段程式根本沒有被執行

有時候最簡單的答案就是:

它真的沒走這條路

例如:

if (user == null)
{
    return NotFound();
}

_userService.Update(user);

我把 Breakpoint 下在:

_userService.Update(user);

user 一直都是 null。

那程式會在前面:

return NotFound();

就結束。

當然永遠不會跑到 Update。

所以這時需要開始看:

程式實際走哪一條判斷?

這也是 Debug 真正有價值的地方。

中斷點不一定要下在 Controller

一開始學中斷點,很容易只會在 Controller 下。

其實只要是會執行的 C# 程式,都可以視情況下中斷點。

例如:

Controller
Service
Repository
資料轉換方法
Helper

假設我已經確定 Controller 正常:

var model = _userService.GetDetail(id);

但 Service 結果不對。

那我就直接去 Service:

public UserDetailViewModel GetDetail(int id)
{
    ...
}

裡下中斷點。

這樣不用每次都從 Controller 慢慢 F11 進去。

所以我的做法會是:

第一次不知道問題在哪
↓
從入口開始追

已經大概知道是哪一層
↓
直接在那一層下中斷點

實際 Debug 一個「資料沒有顯示」的問題

假設畫面上:

部門名稱沒有顯示

View:

@Model.DepartmentName

上一篇可以用 F12 一路找到:

public UserDetailViewModel GetDetail(int id)
{
    var user = _userRepository.GetById(id);

    var model = new UserDetailViewModel
    {
        Name = user.Name,
        DepartmentName = user.DepartmentName
    };

    return model;
}

接著我可以在:

var user = _userRepository.GetById(id);

下 Breakpoint。

按 F5 操作畫面。

停下來後:

先確認 id 是多少

按 F10,讓 Repository 執行完。

接著確認:

user 有沒有資料?
user.DepartmentName 是不是空的?

如果:

user.DepartmentName 已經是空的

就繼續往 Repository 查。

如果:

user.DepartmentName = "資訊部"

但最後 View 還是沒有。

那問題可能在:

Entity / DTO
↓
ViewModel 轉換
↓
Controller
↓
View

後面的某一段。

這時就不用第一時間去改 SQL。

中斷點真正的用途不是「讓程式停住」

我後來覺得 Debug 最重要的觀念其實是:

不要再猜程式怎麼跑
直接讓它跑給我看

例如我原本猜:

按下儲存
↓
Update Controller
↓
Update Service
↓
Database

但中斷點一跑才發現:

按下儲存
↓
另一支 Action
↓
直接 return

那前面猜半天根本沒用!!

所以中斷點是在幫我回答:

這次到底跑了哪支程式?

有沒有進這個方法?

哪個 if 被走到了?

哪裡提早 return?

資料在哪一層開始不對?

我現在會怎麼用中斷點?

假設接到需求:

按下按鈕後沒有反應

我現在不會立刻亂改。

我會先:

第一步
找到按鈕送去哪個 Controller / Action

↓

第二步
在 Action 第一段有效程式下中斷點

↓

第三步
F5 啟動 Debug

↓

第四步
回瀏覽器重現問題

↓

第五步
確認中斷點有沒有被打到

如果沒打到:

先查 Route / Action / HTTP Method

如果有打到:

開始 F10 / F11 往下追

這樣問題就被拆成:

根本沒進來

還是:

有進來,但執行途中出問題

這兩種情況完全不一樣。

常用快捷鍵整理

快捷鍵 功能 我怎麼記
F9 新增 / 移除中斷點 在這裡設一個暫停點
F5 開始 / 繼續 Debug 繼續跑
F10 Step Over 跨過去~下一行,不進方法
F11 Step Into 鑽進去!進方法裡面

再加上一篇的:

F12
找程式寫在哪裡

目前其實已經可以做到:

F12
找到程式

↓

F9
設中斷點

↓

F5
執行

↓

F10 / F11
一步一步追

這已經是我覺得看企業專案非常實用的一組基本工具。

這篇先記住什麼?

F12 可以讓我知道:

程式碼寫在哪裡

Breakpoint 則可以讓我知道:

程式執行時到底有沒有跑到這裡

基本流程:

找到想確認的程式
↓
F9 下 Breakpoint
↓
F5 開始 Debug
↓
操作網站
↓
Visual Studio 停住
↓
F10 / F11 繼續追

其中:

F10
執行下一步,但不要進方法

F11
進到方法裡繼續看

而如果 Breakpoint 完全沒有停:

不要急著改這段程式

先確認:

是不是找錯 Action?
GET / POST 有沒有看錯?
Route 有沒有走這裡?
目前是不是 Debug 正確的專案?
程式是不是在前面就 return 了?

最重要的改變其實是:

以前:

我覺得程式「應該」會跑這裡

現在:

我直接用 Breakpoint 確認
它「到底」有沒有跑這裡

不過程式停下來之後,下一個問題馬上就來了:

好,它真的停了。

然後咧?

現在我要看哪裡?
id 是多少?
model 裡有什麼?
user 為什麼是 null?
這麼多視窗到底要看哪一個?

下一篇就繼續:

程式停下來之後要看什麼?怎麼用變數提示、Locals、Watch 和 Call Stack 找出資料到底在哪裡開始出問題?


上一篇
Day 22|用 F12 從 Controller 追到 Service,資料怎麼一路查到資料庫?
下一篇
Day 24|程式停下來之後看什麼?變數、Locals、Watch 和 Call Stack
系列文
學過一點 React,卻被撈進 C#:新手用 AI 硬啃 MVC 企業專案的 3 個月實錄24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言