在多线程 C# 应用程序中使用断点

问题描述 投票:0回答:1

当您在多线程 C# 应用程序中遇到断点时,我以为所有线程都已停止。
这被 ChatGPT “确认”了(只要这可以确认任何事情:-)),但 ChatGPT 提到了“冻结”和“解冻”线程。

所以,我预计,当遇到断点时,我能够解冻其他线程,但相反,我有可能冻结其他线程,如下面的屏幕截图所示:

Screenshot

一开始这引起了一些混乱。

现在我认为情况是这样的:

  • 命中断点会暂停所有线程。
  • “冻结”功能意味着,即使在断点后继续,我也有可能暂停其他线程。
  • 如果我想“解冻”这些线程,我可以暂停我的应用程序(这也意味着“暂停所有线程”),然后解冻这些线程。

有人可以证实我的想法或更正它吗? (我想强调的是,我正在使用 C# (.Net),其中多线程的处理方式可能与本机语言不同。)
有没有任何文件可以证实这一点?

提前致谢

c# multithreading debugging breakpoints freeze-thaw
1个回答
0
投票

实际上,您可以使用三种正交机制:1)由于您的代码而导致线程进入等待状态,例如,当线程调用像

System.Threading.WaitHandle.WaitOne
这样的阻塞调用时,2)冻结状态,3)断点处的等待状态,机制 #2 和 #3 适用于调试器下的执行。

请注意,方法

System.Threading.Thread.Suspend
Freeze 类似(甚至效果相同),但目前已被
System.ObsoleteAttribute
标记为过时,因此您无法执行此调用。这个决定有一些重要的原因:如果您还有其他问题,我们可以讨论。但是,您仍然可以使用 System.Threading.Thread.Sleep 使用
infinite
超时值将线程置于永远 等待状态。它在某些罕见的情况下可能很有用,但自然并不总是安全的。

也就是说,任何等待或冻结状态都会阻止线程继续执行。重要的是要理解,等待线程在被唤醒之前不会消耗任何 CPU 时间。它与任何类型的旋转等待完全不同。一个线程让步给其他线程,并且操作系统的调度程序不会将其调度回执行,直到有消息告诉系统唤醒它。它是通过以下方式发生的:1) 解锁调用,例如,通过发出

WaitHandle
互斥锁、锁定、信号量、阻塞读取调用等信号,2) 通过命令 Thaw,3) 通过在断点处命令 continue 。但是,如果满足其继续执行的其他两个条件,则线程将被唤醒以继续执行。

这里,控制线程执行的代码方面,各种阻塞调用,IPC,同步等等,我就不详细讨论了。这是一个很大的单独话题。我刚刚将这一方面归为一大类#1。

最重要的是,您可以控制调试器下的执行。例如,对于 Visual Studio,您可以使用断点、主菜单 > 调试 > 开始调试继续 (F5)、主菜单 > 调试 > Windows > 线程 > 上下文菜单 > 冻结解冻命令。

© www.soinside.com 2019 - 2024. All rights reserved.