Visual Studio 2019社区版调试时悬停变量无法显示值如何解决
问题描述
我使用的是Visual Studio 2019社区版,相关代码如下:
private void CreateDownloadFolders() { string locationToCreateFolderRadar = textBoxRadarPath.Text; string locationToCreateFolderSatellite = textBoxSatellitePath.Text; string folderName = ""; string date = DateTime.Now.ToString("ddd MM.dd.yyyy"); string time = DateTime.Now.ToString("HH.mm tt"); string format = "{0} On {1} {2}"; folderName = string.Format(format, date, time, ""); var p = Path.Combine(locationToCreateFolderRadar + folderName); Directory.CreateDirectory(locationToCreateFolderRadar + folderName); Directory.CreateDirectory(locationToCreateFolderSatellite + folderName); }
我在如下代码行设置了断点:
Directory.CreateDirectory(locationToCreateFolderRadar + folderName);
代码执行到此处中断后,我将鼠标悬停在字符串变量locationToCreateFolderRadar上,无法显示其内容,该方法内的其他变量也存在同样问题。
该方法是从以下按钮点击事件中调用的:
private async void btnStart_Click(object sender, EventArgs e) { CreateDownloadFolders(); urls = new List<string>(); lblStatus.Text = "Downloading..."; rad.GetRadarImages(); await Task.Delay(5000); foreach (string link in rad.links) { urls.Add(link); } await sat.DownloadSatelliteAsync(); foreach (string link in sat.SatelliteUrls()) { urls.Add(link); } urlsCounter = urls.Count; await DownloadAsync(); }
下方为断点触发后悬停变量无内容显示的截图:
原因分析
- 项目运行在Release模式下,Release模式默认会对代码做编译优化,局部变量会被内联、回收,调试器无法追踪变量的存储信息
- 即使是Debug模式,项目生成配置中开启了「优化代码」选项,同样会导致调试信息丢失
- VS调试配置异常,关闭了属性评估、隐式函数调用等调试必备的选项
- 源代码和编译生成的pdb调试文件不匹配,运行的是旧版本的编译结果
- 调用方为
async void类型的异步事件方法,异步上下文偶尔会导致调试器变量追踪失效
解决方案
- 切换运行模式为Debug
点击VS顶部工具栏的运行模式下拉框,选择Debug,不要使用Release模式,重新编译运行项目测试 - 关闭代码优化配置
右键当前项目 -> 选择「属性」-> 切换到「生成」选项卡,确认「优化代码」的勾选框处于未选中状态,保存配置后重新编译 - 重置VS调试配置
打开VS顶部菜单栏的「工具」->「选项」->「调试」->「常规」,勾选以下配置:
- 启用属性评估和其他隐式函数调用
- 允许对对象进行字符串转换
- 在变量窗口中显示对象的原始结构
保存配置后重启VS再测试
- 清理并重新生成解决方案
点击顶部菜单栏「生成」->「清理解决方案」,清理完成后再点击「生成」->「重新生成解决方案」,确保pdb调试文件和当前源代码完全匹配 - 强制方法不被优化
若以上方案都无效,可以给CreateDownloadFolders方法添加特性,强制调试器不对该方法做优化:
using System.Runtime.CompilerServices; [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)] private void CreateDownloadFolders() { // 原有方法逻辑 }
也可以在断点命中后,通过「局部变量」「自动」窗口查看变量值,或者在即时窗口输入变量名打印值。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

