Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >VS 2022调试技巧:远程调试、线程检查、性能检查

VS 2022调试技巧:远程调试、线程检查、性能检查

作者头像
郑子铭
发布于 2023-08-30 00:23:25
发布于 2023-08-30 00:23:25
1.5K00
代码可运行
举报
运行总次数:0
代码可运行

前言

visual studio一直都是.net/c#开发人员最受欢迎的编译器,除了强大的代码提示和项目模板,还拥有大量的调试工具,这一期我们介绍下code freeze阶段的一些调试技巧。包括测试环境/生产环境下的远程调试,线程调试,以及性能监控调试。

一、远程调试

当我们的程序所在的目标机器没有跑源码所需的sdk或者没办法安装vs的时候,我们需要对目标机器上正在运行或者即将运行的应用进行调试。我们通过远程调试在本机上对目标机器调试。

1、安装

Remote Debug下载地址:

https://visualstudio.microsoft.com/zh-hans/downloads/?rr=https://docs.microsoft.com/en-us/visualstudio/debugger/remote-debugging?view=vs-2019

选择下载进行安装,最后管理员运行。

查看目标机运行所使用的端口号

2、调试

1、调试->附加进程

修改对应的目标主机的端口和IP地址

2、选中对应的进程点击附加

3、我们贴上一段代码,代码会死循环打印一个自增的数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static void Main(string[] args)
{
    int i = 0;
    while (true) 
    {
        Console.WriteLine(++i);
        Thread.Sleep(1000);
    }
}

我们在目标主机运行起来,然后在本地利用源码进行远程调试,并且加上一个断点。

发现断点进来了,并且程序不再打印,则调试成功。

二、线程调试

我们可以利用visual studio的线程窗口来查看目前所有的活动线程的运行情况以及线程目前在代码何处运行。

该功能配合远程调试可以很好的观察生产或者测试环境下的死锁问题。当然开发环境下也一样。

我们来调查一个死锁。

先实现一个简单的死锁程序:声明两个锁对象,并且用两个线程各自占用一个锁,再去索要另外一个锁,形成死锁。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static object _lock = new object();
private static object _lock_1 = new object();
static void Main(string[] args)
{
    var task1 = Task.Run(DeadLock);
    var task2 = Task.Run(DeadLock_1);

    Task.WaitAll(task1,task2);
    Console.WriteLine("Hello, World!");
}

private static void DeadLock()
{
    lock (_lock)
    {
        Thread.Sleep(200);
        lock (_lock_1)
        {
            Console.WriteLine("DeadLock");
        }
    }
}

private static void DeadLock_1()
{
    lock (_lock_1)
    {
        Thread.Sleep(200);
        lock (_lock)
        {
            Console.WriteLine("DeadLock_1");
        }
    }
}

运行程序之后,将程序中断

点击调试->窗口->线程

可以看到两个工作线程,双击可以查看该线程中断时所处的位置。从而可以分析线程是否阻塞在这里,是否是形成问题的关键。

三、性能调试

VS自带的性能监控工具提供了一些数据的监控和分析,比较常用的就是CPU使用和内存IO的监控。它支持本地启动项目的监控以及进程和可执行程序的附加。

点击调试->性能追踪(Performance Profiler)

我们来实现一个CPU密集型的代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static async Task Main(string[] args)
{
    await MultiRunning();
    SomeThing();
    Console.WriteLine("Hello, World!");
}

//启动20个线程
static async Task MultiRunning()
{
    Thread[] tasks = new Thread[20];
    foreach (var index in Enumerable.Range(0, tasks.Length))
    {
        tasks[index] = new Thread(() =>
        {
            while (true)
            {
                int a = 1;
                Thread.Sleep(200);
            }
        });
    }

    int i = 0;
    await Parallel.ForEachAsync(tasks, (task, source) =>
    {
        i++;
        task.Start();
        return ValueTask.CompletedTask;
    });

    Console.WriteLine("执行了" + i);
}

static void SomeThing()
{
    while (true)
    {
        Console.WriteLine("I AM Alive");
        Thread.Sleep(200);
    }
}

我们使用Performance Profiler对启动项目的CPU进行监控。

当我们觉得程序运行的差不多了,我们可以点击停止搜集,然后visual studio会给我们生成一些分析数据

点击打开详情,然后根据函数来分析占用的CPU,默认也是按照函数所占用的CPU时间片来进行排序。选择我们程序的函数,双击Main函数,可以看到里面的方法各自的占用,从而判断找出高CPU的函数。

以此类推,如果需要寻找高IO的根源点,也可以使用VS自带的Performace Profiler来追踪代码的执行性能。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
.Net多线程编程—误用点分析
1 共享变量问题 错误写法: 所有的任务可能会共享同一个变量,所以输出结果可能会一样。 1 public static void Error() 2 { 3 for(int i=0;i<10;i++) 4 { 5 Task.Run(() => { Console.WriteLine("{0}", i); }); 6 } 7 } 正确写法: 将变量i赋给局部变量temp,使得每一个任务使用不同的i值。 1
甜橙很酸
2018/03/08
9120
.Net多线程编程—误用点分析
C#多线程和异步(二)——Task和async/await详解
  同步和异步主要用于修饰方法。当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法;当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调用者不用等待该方法执行完毕,我们称这个方法为异步方法。
zls365
2021/02/26
7.2K0
C#:异步编程中的 async 和 await
async 和 await 在 C# 5.0 就已经引入了,用来处理异步编程,但之前用的相对较少,现在在 dotNet Core 时代,已经使用的非常普遍,很多的开源组件中提供了大量的后缀为 Async (异步)的方法。本文就简单讲讲 async 和 await。
oec2003
2020/11/19
2.7K0
C#:异步编程中的 async 和 await
【深入浅出C#】章节 9: C#高级主题:多线程编程和并发处理
多线程编程和并发处理的重要性和背景 在计算机科学领域,多线程编程和并发处理是一种关键技术,旨在充分利用现代计算机系统中的多核处理器和多任务能力。随着计算机硬件的发展,单一的中央处理单元(CPU)已经不再是主流,取而代之的是多核处理器,这使得同时执行多个任务成为可能。多线程编程允许开发人员将一个程序拆分成多个线程,这些线程可以并行执行,从而提高程序的性能和响应速度。 为什么多线程在现代应用中至关重要?
喵叔
2023/08/26
5K0
异步与多线程——c#
异步这概念刚开始接触的时候,不是那么容易接受,但是需要用的地方还真的挺多的,刚学习的时候,也很懵逼走了不少弯路,所以这里有必要总结一下。 msdn文档:https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/ 官方的简介: *.NET Framework提供了执行异步操作的三种模式: 异步编程模型(APM)模式(也称为IAsyncResult的模式),其中异步操作要求Begin和End方法(例如,BeginWrite和EndWrite异步写入操作)。这种模式不再被推荐用于新开发。有关更多信息,请参阅异步编程模型(APM)。
vv彭
2021/01/07
1.7K0
异步与多线程——c#
C# 并行和多线程编程——认识和使用Task
 对于多线程,我们经常使用的是Thread。在我们了解Task之前,如果我们要使用多核的功能可能就会自己来开线程,然而这种线程模型在.net 4.0之后被一种称为基于“任务的编程模型”所冲击,因为task会比thread具有更小的性能开销,不过大家肯定会有疑惑,任务和线程到底有什么区别呢?
用户9127601
2021/11/01
8630
.NET 各版本多线程使用原理与实践
多线程编程是现代应用程序开发中的核心技术,尤其是在需要并发处理或提升性能的场景中。本文将以 .NET 各版本为背景,详细探讨多线程技术的发展、底层原理以及实践方法。
Michel_Rolle
2024/11/19
2.2K0
ConcurrentDictionary线程不安全么,你难道没疑惑,你难道弄懂了么?
事情不太多时,会时不时去看项目中同事写的代码可以作个参考或者学习,个人觉得只有这样才能走的更远,抱着一副老子天下第一的态度最终只能是井底之蛙。前两篇写到关于断点传续的文章,还有一篇还未写出,后续会补上,这里我们穿插一篇文章,这是我看到同事写的代码中有ConcurrentDictionary这个类,之前并未接触过,就深入了解了一下,所以算是查漏补缺,基础拾遗吧,想要学习的这种劲头越有,你会发觉突然涌现的知识越多,学无止境!。
yaphetsfang
2020/07/30
7860
ConcurrentDictionary线程不安全么,你难道没疑惑,你难道弄懂了么?
async & await 的前世今生(Updated)
async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了。但是这也给我们编程埋下了一些隐患,有时候可能会产生一些我们自己都不知道怎么产生的Bug,特别是如果连线程基础没有理解的情况下,更不知道如何去处理了。那今天我们就来好好看看这两兄弟和他们的叔叔(Task)爷爷(Thread)们到底有什么区别和特点,本文将会对Thread 到 Task 再到 .NET 4.5的 async和 await,这三
用户1153966
2018/03/14
7880
async & await 的前世今生(Updated)
ConcurrentDictionary字典操作竟然不全是线程安全的?
标题不准确,实际上ConcurrentDictionary<TKey,TValue>绝大部分api都是线程安全且原子性的[1], 唯二的例外是接收工厂函数的api:AddOrUpdate、GetOrAdd,这两个api不是原子性的,需要引起重视。
有态度的马甲
2022/12/21
6120
ConcurrentDictionary字典操作竟然不全是线程安全的?
C# 中的线程与任务 — 有什么区别?
在C#编程中,类(class)是一种让我们可以同时执行任务的方式,允许我们在程序的其他部分继续运行时执行代码。尽管现代C#开发人员通常使用Task来管理并发性,但Thread类提供了更多的线程行为控制,这使得它在需要进行低级别线程操作时非常有用。
郑子铭
2025/01/07
1920
C# 中的线程与任务 — 有什么区别?
为什么 Random.Shared 是线程安全的
在多线程环境中使用 Random 类来生成伪随机数时,很容易出现线程安全问题。例如,当多个线程同时调用 Next 方法时,可能会出现种子被意外修改的情况,导致生成的伪随机数不符合预期。
newbe36524
2023/08/23
2850
线程详解——c#
使用线程,我们需要引用System.Threading命名空间。创建一个线程最简单的方法就是在 new 一个 Thread,并传递一个ThreadStart委托(无参数)或ParameterizedThreadStart委托(带参数),如下:
vv彭
2020/12/16
4380
线程详解——c#
[C#] Task.CompletedTask和Task.Result什么时候用?
在学习C#中的Task方法时,可以知道Task启动一个异步线程方法可以用Task.Run()进行,具体可以参看附录部分。
科控物联
2023/09/01
2.2K0
[C#] Task.CompletedTask和Task.Result什么时候用?
C#多线程(14):任务基础②
上一篇,我们学习了任务的基础,学会多种方式场景任务和执行,异步获取返回结果等。上一篇讲述的知识比较多,这一篇只要是代码实践和示例操作。
痴者工良
2021/04/26
7430
c#线程-线程同步
如果有多个线程同时访问共享数据的时候,就必须要用线程同步,防止共享数据被破坏。如果多个线程不会同时访问共享数据,可以不用线程同步。 线程同步也会有一些问题存在: 1、性能损耗。获取,释放锁,线程上下文建切换都是耗性能的。 2、同步会使线程排队等待执行。
苏州程序大白
2021/08/13
7740
C# 多线程编程入门教程
随着硬件性能的提升,尤其是多核CPU的广泛应用,多线程编程已经成为现代软件开发中的核心技能之一。多线程可以让程序在多个核心上并发运行,提高效率和性能。然而,编写多线程程序并不是一件简单的事情,尤其是要处理线程间的同步问题,以避免数据竞争和死锁等问题。
Michel_Rolle
2024/09/23
2.7K0
C#学习笔记 线程同步问题
生产者消费者问题大体是这样的:有几个生产者和几个消费者,共享一个缓冲区。生产者会向缓冲区中添加数据;消费者会从缓冲区中将数据取走。需要处理这两者之间的同步问题。
乐百川
2022/05/05
3650
.NET系列走进Task:Task的回调执行与await
上一篇我们讲了对 Task 的基本定义:Task 代表一个任务,其具体类型可能是多种多样的,且有时候对我们来说完全是个黑盒。这个任务可以有结果,可以没有结果,我们能知道这个任务什么时候执行完成,并进行相应的后续处理。
郑子铭
2022/03/22
2.7K0
.NET系列走进Task:Task的回调执行与await
.NET中Thread、Task或Parallel实现多线程的使用总结
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。本文主要介绍.NET(C#) 中使用Thread、Task或Parallel实现多线程的总结,以及相关的示例代码。
郑子铭
2023/08/30
4980
.NET中Thread、Task或Parallel实现多线程的使用总结
相关推荐
.Net多线程编程—误用点分析
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验