C#比较两个对象是否为同一个对象。 Visual Studio调试器指南---多线程应用程序调试(一)
两个对象是否为同一个对象:是看两个对象是否指向堆中的同一块内存。
1、使用object.ReferenceEquals()
class Program { static void Main(string[] args) { Person p1 = new Person(); p1.Name = "Mark"; Person p2 = new Person(); p2.Name = "Marl"; Person p3 = p1; Console.WriteLine(object.ReferenceEquals(p1,p2)); Console.WriteLine(object.ReferenceEquals(p1,p3)); } class Person { public string Name { get; set; } } }
//结果:false。
true
2.使用object.equals()
class Program { static void Main(string[] args) { Person p1 = new Person(); p1.Name = "Mark"; Person p2 = new Person(); p2.Name = "Marl"; Person p3 = p1; Console.WriteLine(p1.Equals(p2)); Console.WriteLine(p1.Equals(p3)); } class Person { public string Name { get; set; } } }
//结果同上
3、使用== 得到同样的结果。
目前来看,这三个方法都能判断两个对象是否为同一个对象。但是:
static void Main(string[] args) { string s1 = new string(new char[] { 'a', 'b' }); string s2 = new string(new char[] { 'a', 'b' }); Console.WriteLine(s1==s2);//true Console.WriteLine(s1.Equals(s2));//true Console.WriteLine(object.ReferenceEquals(s1,s2));//false }
这两个s1,s2是两个不同的对象,因为new了两次,在堆中存在两块不同的内存。
总结:
Equals:内部是判断两个对象中的值是否一样。
==:内部还是调用的equals方法,所以应该同上。
所以用第一种。
使用多个线程的并行处理可以极大地提高程序性能,但也可能导致调试变得更加困难,因为正在跟踪多个线程。
死锁通常是一个难以调试的问题。
用于调试多线程应用的工具
Visual Studio 提供不同的工具用于调试多线程应用程序。
-
-
-
对于调试 GPU 上的线程,主要工具是“GPU 线程”窗口。
-
对于进程,主要工具是“附加到进程”对话框、“进程”窗口和“调试位置”工具栏。
使用跟踪点可以在不中断的情况下跟踪程序的执行,从而研究死锁之类的问题。
可以考虑在另一台计算机上运行应用程序并使用远程调试。
参考网址:https://www.cnblogs.com/yilang/p/12487588.html
-
在
代码
行上设置断点,方法是单击左侧的滚动条线,或选择线条并按F9。断点在代码行旁边的左侧滚动条中显示为红色圆圈。 -
应用程序在调试模式下启动,并在断点处暂停。
-
检查线程标记
-
图标。
-
-
右键单击源代码中的线程标记可查看快捷菜单上的可用选项。
标记线程和取消标记线程
您可以标记线程以跟踪您要特别注意的线程。
从任何位置进行的选择将影响所有位置。
在源代码中标记和取消标记线程
-
-
在线程列表中,当前正在执行的线程由 > 符号标记。
-
标志图标变为红色。
-
除非标记一个或多个线程,否则图标为灰显。
提示
将标记的线程运行到光标处将暂停选定代码行上的线程,从而可以更轻松地通过冻结和解冻线程控制执行顺序。
-
标记当前线程对于仅显示标记的线程时查找当前线程非常有用。
-
选择标记图标,以根据其当前状态将线程状态更改为标记或未标记。
其他线程窗口功能
如果显示了所有线程,则选择标志图标列会按标记或未标记的状态对线程进行排序。
此列中的黄色箭头标记当前执行点。
选择Location项旁边的展开箭头,或将鼠标悬停在该项上,以显示该线程的部分调用堆栈。
除了标记 、取消标记和取消标记所有线程外,线程窗口项的右键单击上下文菜单还具有:
- 切换到线程,这会立即将执行切换到该线程。
- 重命名,使你可以更改线程名称。
- 冻结和解冻命令。
冻结和解冻线程执行
冻结和解冻线程可帮助解决并发性问题,如死锁和争用条件。
提示
若要在不冻结其他线程的情况下跟踪单个线程,这也是一种常见的调试方案,请参阅开始调试多线程应用程序。
冻结和解冻线程:
-
-
冻结线程的挂起计数值为1。
-
切换到另一个线程
此窗口提供了解决此问题的建议。
切换到另一个线程:
-
你需要切换回此线程以继续运行你的应用程序。
-
-
原始的当前线程标记也保留为轮廓。
观察当前线程是否也已更改。
-
请注意,当前线程还会在其他两个位置发生更改。
-
观察当前线程是否在所有三个位置发生了更改。
使用“线程”窗口和“调试位置”工具栏可以切换到任何线程。
使用多个线程的并行处理可以极大地提高程序性能,但也可能导致调试变得更加困难,因为正在跟踪多个线程。
死锁通常是一个难以调试的问题。
用于调试多线程应用的工具
Visual Studio 提供不同的工具用于调试多线程应用程序。
-
-
-
对于调试 GPU 上的线程,主要工具是“GPU 线程”窗口。
-
对于进程,主要工具是“附加到进程”对话框、“进程”窗口和“调试位置”工具栏。
使用跟踪点可以在不中断的情况下跟踪程序的执行,从而研究死锁之类的问题。
可以考虑在另一台计算机上运行应用程序并使用远程调试。
参考网址:https://www.cnblogs.com/yilang/p/12487588.html
-
在
代码
行上设置断点,方法是单击左侧的滚动条线,或选择线条并按F9。断点在代码行旁边的左侧滚动条中显示为红色圆圈。 -
应用程序在调试模式下启动,并在断点处暂停。
-
检查线程标记
-
图标。
-
-
右键单击源代码中的线程标记可查看快捷菜单上的可用选项。
标记线程和取消标记线程
您可以标记线程以跟踪您要特别注意的线程。
从任何位置进行的选择将影响所有位置。
在源代码中标记和取消标记线程
-
-
在线程列表中,当前正在执行的线程由 > 符号标记。
-
标志图标变为红色。
-
除非标记一个或多个线程,否则图标为灰显。
提示
将标记的线程运行到光标处将暂停选定代码行上的线程,从而可以更轻松地通过冻结和解冻线程控制执行顺序。
-
标记当前线程对于仅显示标记的线程时查找当前线程非常有用。
-
选择标记图标,以根据其当前状态将线程状态更改为标记或未标记。
其他线程窗口功能
如果显示了所有线程,则选择标志图标列会按标记或未标记的状态对线程进行排序。
此列中的黄色箭头标记当前执行点。
选择Location项旁边的展开箭头,或将鼠标悬停在该项上,以显示该线程的部分调用堆栈。
除了标记 、取消标记和取消标记所有线程外,线程窗口项的右键单击上下文菜单还具有:
- 切换到线程,这会立即将执行切换到该线程。
- 重命名,使你可以更改线程名称。
- 冻结和解冻命令。
冻结和解冻线程执行
冻结和解冻线程可帮助解决并发性问题,如死锁和争用条件。
提示
若要在不冻结其他线程的情况下跟踪单个线程,这也是一种常见的调试方案,请参阅开始调试多线程应用程序。
冻结和解冻线程:
-
-
冻结线程的挂起计数值为1。
-
切换到另一个线程
此窗口提供了解决此问题的建议。
切换到另一个线程:
-
你需要切换回此线程以继续运行你的应用程序。
-
-
原始的当前线程标记也保留为轮廓。
观察当前线程是否也已更改。
-
请注意,当前线程还会在其他两个位置发生更改。
-
观察当前线程是否在所有三个位置发生了更改。
使用“线程”窗口和“调试位置”工具栏可以切换到任何线程。