先说说我为什么会对“分窗口看输出”这件事上瘾。我在 Rider 里跑一个 ASP.NET Core Web API,启动不到三秒,控制台就开始滚屏:Microsoft.AspNetCore 的 Info 日志、HTTP 请求记录、EF Core 的 SQL 命令、我自己的 Console.WriteLine,还有偶发的警告。一旦切换到 Debug 模式跑起来,底部工具窗口更是把调试器的输出也塞进来——哪个程序集加载了、哪个线程崩了、捕获到异常了……全都跟业务日志糊在同一块区域。想顺顺利利地分窗口看 console 和 debug 的输出,成了我当时最想解决的问题。
Rider 确实可以做这件事,而且不止一种方式。这篇文章我会把几种分窗方案讲透,顺带整理一些调试输出控制、日志降噪、常见排坑技巧。无论你是刚转到 JetBrains 生态的 .NET 开发者,还是长期在 Rider 里写大型项目的老人,下面这些实操配置都值得直接抄走。
1. 别让日志糊成一锅粥:先搞清楚两类输出的区别
1.1 Console 与 Debug:一个是业务日志,一个是调试线索
很多人在 Rider 里分不清“控制台输出”和“调试输出”,本质上是因为这两类信息在界面上一开始是叠在一起的。先理清它们的来源,后面的分窗操作才有意义。
控制台输出(Console 输出)对应的是进程的标准输出流(stdout)和标准错误流(stderr)。你写的Console.WriteLine、Console.Error.WriteLine、第三方库打到控制台的日志、ASP.NET Core 的日志系统输出,全都在这个范畴里。它属于“业务运行日志”,是用来观察程序当下做了什么、有没有报错的主通道。
调试输出(Debug 输出)则来自调试器本身,以及代码里使用了Debug.WriteLine、Trace.WriteLine这类诊断 API。它更像“调试者的速记本”:哪个模块被加载了、哪个异常被首次抛出、条件断点命中了没、线程是几号,这类信息通常只在调试会话中才有意义。特别需要注意的是,Debug.WriteLine只有在编译符号DEBUG存在时才会生效,如果你用 Release 配置运行,这一行代码实际上会被编译器拿掉,不会产生任何输出。
把这两个东西硬塞进同一个窗口当然也能看,但一旦日志量上来,互相干扰就非常明显。表里简单对比一下:
| 对比维度 | Console 输出 | Debug 输出 |
|---|---|---|
| 写入方式 | Console.WriteLine、日志框架 | Debug.WriteLine、Trace.WriteLine |
| 目标流 | stdout / stderr | 调试器诊断通道 |
| 存在条件 | 始终存在 | DEBUG 编译符号开启时才存在(Debug.WriteLine) |
| 典型内容 | 请求日志、业务返回、错误堆栈 | 模块加载、线程事件、异常抛出、断点日志 |
| 适合查看方式 | 独立窗口看业务运行情况 | 独立窗口看调试器内部发生了什么 |
1.2 Rider 工具窗口的真实结构:Run 窗口、Debug 标签、Build 标签
默认情况下,你用调试模式运行程序(Rider 里对应快捷键Shift+F9),IDE 底部的 Run 工具窗口会弹出来。这个工具窗口并不是只有一个面板,标题栏下面通常有一排标签页:Run、Debug、Build、Tests、Version Control、NuGet 等。注意,这里的Run 标签页展示的是程序的标准输出,Debug 标签页展示的是调试器输出,两者本来就存在,只是默认被压缩在同一个工具窗口里。
这就是“分窗口看 console 和 debug 输出”最直接的前提条件:数据没丢,只是显示策略把它们合并了。Rider 还提供了一个输出模式切换器,位置就在 Run 工具窗口的顶部工具栏区域,允许你选择只显示 Run 输出、只显示 Debug 输出,或者显示 All Output。如果你不想分窗,用这个切换器快速过滤也是一种轻量方案。
不过光靠切换器还是有局限,你没法同时看到两个面板。想要真正各看各的,就得用下面的分窗操作。
1.3 Console 这个词的多义性,先替你排个雷
很多人在搜资料时会发现,Console 这个词在开发圈里同时指好几样东西:路由器背后的串行配置口(华为路由器的 console 配置接口)、音频厂商的 Realtek Audio Console 控制面板、浏览器开发者工具里的 Console 面板、HBuilderX 内置浏览器里的调试控制台。这些“Console”和 Rider 里的控制台输出完全是两码事,别被关键词带偏。Rider 的 Console 指的是 IDE 内捕获到的标准输出流,就是你代码里打印出去、能被终端捕获到的那个通道。
2. 实操:三种分窗方式,把 Run 和 Debug 彻底分离
2.1 方法一:右键标签页 “Split and Move Right”,快速垂直分屏
这是我觉得最顺手的方法,不需要拖拽,也不用记菜单路径,鼠标点两下就完成。
步骤如下:
- 用
Shift+F9启动调试模式,让底部出现 Run 工具窗口。 - 在标签栏上找到Debug标签,右键点击。
- 在弹出菜单中选择Split and Move Right(如果希望窗口在下方,可以选择 Split and Move Bottom)。
- IDE 会把 Debug 标签单独拆出来,停靠在编辑器右侧区域,原来的 Run 标签保留在底部左侧。
执行完后,你的布局会变成这样:左侧/下方是控制台输出(Run),右侧是调试输出(Debug)。程序一跑起来,业务日志和调试器信息就各走各的通道,再也不用在两个标签页之间反复点来点去。
想撤销也简单,右键拆分出来的标签页,选择 Merge All 相关选项,或者直接把标签拖回原来的工具窗口区域即可。这个拆分操作在 JetBrains 系 IDE 里是通用的,IntelliJ IDEA、PyCharm 上同样适用。
2.2 方法二:拖拽停靠:自由排列到 IDE 右侧或下方
如果你不喜欢 Split and Move Right 这种固定方向的拆分,可以用更自由的拖拽停靠方式。
按住 Debug 标签页的标题,慢慢往外拖,当鼠标移到 IDE 右侧边缘时,屏幕上会出现一个垂直方向的停靠预览阴影;如果移到下方边缘,则是水平方向的预览阴影。看到阴影后松开鼠标,标签页就会停靠到你想要的位置。
有一点值得提醒:拖拽时如果落点在编辑器代码区域的中间而不是窗口边缘,Rider 会把这个工具窗口变成浮动窗口,而不是停靠窗口。很多新手在这里会误会,以为自己在分屏,实际是把窗口“浮”出来了。想分开看但不想让窗口飘在代码上面,一定要拖到边缘再松开。
用拖拽方式的好处是灵活,你可以把 Run 窗口放在底部,Debug 窗口放在右侧,形成一个“L”形布局,也可以把 Run 放在左边、Debug 放在右边,直接左右分屏。停靠完成后,拖动两个窗口之间的分隔条,还能实时调整各自占的宽度。
2.3 方法三:浮动窗口与多显示器协作
除了停靠,Rider 还允许把工具窗口完全浮动出来。点击工具窗口右上角的齿轮图标,选择 Floating Mode,Debug 标签会变成独立于主窗口的一个浮动小窗。这个小窗可以自由拖到你屏幕的任何位置,如果你接了双显示器,直接把浮动窗口拖到第二块屏幕上是完全可行的。
我实测这样的体验非常好:主屏幕专心写代码,副屏幕固定放着调试输出窗口,一边断点命中一边看输出,基本不用切换 IDE 视图。如果是单人单屏,浮动窗口的优先级其实不如停靠分窗,因为浮动窗口会遮挡代码区域;但双屏环境下,这个模式比 Split and Move Right 更值得用。
顺带一提,如果你觉得分窗太折腾,只是偶尔想快速切换两个面板,可以直接用Ctrl+Tab弹出窗口切换器,或者点标签页切换。切换本身不花时间,真正花时间的,是在一锅粥里找自己需要的输出。
3. 调试时,把“谁打印、在哪里打印”管明白
3.1 用断点日志打印代替临时代码,输出到 Debug 窗口
调试时最烦的一件事,就是为了看一个变量的值,临时往代码里塞Console.WriteLine,调试完还要记得删。Rider 提供了一个更干净的做法:右键断点,在断点设置里勾选Log message或Log evaluated expression,然后填写要打印的文本模板,比如进入订单处理流程,订单ID=$orderId。
这个功能会在断点命中时向 Debug 输出窗口写一条日志,但它仍然执行程序,不会中断。断点还可以和 Condition 配合,比如只在orderId > 100时输出,或者在满足某个条件时才打印。这样做的好处非常明显:
- 不用改源码,不用重新编译。
- 输出统一进 Debug 标签页,不会污染 Console 的业务日志。
- 删除断点即清理干净,不会把临时日志留在代码里。
配合前面讲的分窗操作,这类日志打印在右侧 Debug 窗口中滚动,业务日志在左侧控制台正常输出,互不干扰。用习惯之后,你会发现自己往代码里塞调试日志的频率大幅下降。
3.2 第一次异常与异常过滤:别让第三方库刷爆调试输出
在 Debug 标签页里,你经常能看到类似Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll这样的信息。这是 CLR 抛出的“第一次异常”通知,也就是异常发生的那一瞬间,无论后续是否会被 catch 住,调试器都会报告一次。
这些信息本身有价值,但如果你的项目引入了很多第三方包,很多库内部会故意“抛出再捕获”来完成流程控制,结果就是 Debug 输出被大量假的异常刷屏。Rider 可以在调试器设置里配置中断策略,大致选项包括:
- Break on all exceptions:所有异常都中断,最严格,一般不建议日常用。
- Break on CLR exceptions:仅 CLR 层面的异常中断。
- Break on User-unhandled exceptions:只在用户代码没有捕获异常时中断,日常调试推荐这个。
如果你只想关注某个特定异常,可以设置过滤规则,只针对特定异常类型或命名空间中断。这样 Debug 输出会干净很多,控制台也不会被干扰。
3.3 给第三方日志降噪:把 Microsoft 框架日志调到 Warning
很多人的控制台之所以会滚屏,不是自己代码写的多,而是 ASP.NET Core 框架日志太多。Microsoft.AspNetCore命名空间下每天会输出大量 Info 级日志,比如“Request starting HTTP/1.1 GET”这类。这些日志在排查性能问题时有用,但日常写业务基本用不上。
解决办法是在appsettings.json里调整日志级别,给一个常见的配置示例:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.AspNetCore": "Warning" } } }配置完成后,框架相关日志只显示 Warning 及以上级别,你自己的业务代码保持默认 Information,控制台立刻安静一个数量级。需要深挖框架内置日志时,再把级别临时改回 Information,排查完再降回来。这种方式不用改代码、不用重启 IDE,重新运行项目即可生效,非常适合日常使用。
4. 让窗口各干各的:颜色区分、过滤器和搜索技巧
4.1 ANSI 颜色加亮:业务日志与错误一眼区分
Rider 控制台窗口原生支持 ANSI 转义序列,这意味着你可以在代码里直接给日志上颜色,不需要任何插件。比如在 .NET 里这样写:
Console.WriteLine("\u001b[32m这是正常业务日志\u001b[0m"); Console.Error.WriteLine("\u001b[31m这是错误日志,一眼就能看到\u001b[0m");\u001b[32m表示绿色,\u001b[31m表示红色,\u001b[0m是重置为默认颜色。实测在 Rider 的 Run 窗口中显示非常稳定,即使程序是通过调试模式启动的,颜色同样能保留。
我自己平时会封装一个简单的日志工具类,用不同的 ANSI 颜色给 Info、Warn、Error 分级,这样控制台窗口里滚动的内容就很有层次感:绿的是正常流程,黄的是警告,红的是错误,一眼就能定位。这个方法同样适用于把 Debug 输出和 Console 输出混合查看的场景,颜色一眼就能区分来源。
4.2 正则过滤器:只看你想看的内容
Rider 输出窗口自带搜索和过滤能力。在 Run 窗口右上角有一个搜索框,除了普通关键字搜索,它还支持正则表达式过滤。比如你只想看自己的业务日志,不看 Microsoft 开头的框架日志,可以在过滤表达式里写:
^(?!Microsoft)这个正则的含义是匹配所有不以 Microsoft 开头的行。实测过滤后,控制台界面里的输出行数骤减,剩下的内容基本就是自己代码和业务库的日志。类似地,你也可以用.*Error.*这类模式快速把错误行捞出来。
需要注意一点:过滤操作只影响显示,不会拦截或删除任何输出。如果你担心日志量太大导致 IDE 卡顿,光靠过滤是不够的,还得结合 3.3 节说的日志级别降噪。
4.3 输出窗口的字体与配色方案调整
如果窗口拆出来了,还是觉得不够直观,可以通过调整 Rider 的 Console 配色来强化视觉区分。在 Settings -> Editor -> Color Scheme -> Console Colors 下,可以设置标准输出、错误输出、系统输出的字体颜色和背景颜色。
我的建议是把 Error 输出设置成红色底或者深红色字,把标准输出保持默认色。相比改默认主题的激进方案,这种局部调整影响面小、效果直接。
这里有个容易踩的坑:JetBrains 工具窗口的背景色是跟随 IDE 主题全局配置的,你不能单独给 Run 窗口和 Debug 窗口设置不同背景色。想在两个窗口之间快速区分,最有效的做法是依赖 ANSI 颜色或者输出内容前缀,而不是指望 IDE 给你开“窗口级个性主题”。
5. 实战场景:多项目、单元测试与跨引擎调试的窗口布局
5.1 同时跑多个项目:用多个 Run 标签并排分窗
开发微服务或者前后端联调时,经常需要同时启动两个服务。Rider 可以在同一个 Run 工具窗口里创建多个运行标签,每个标签对应一个启动配置,标签之间可以来回切换。
配合分窗技巧,你甚至可以同时打开两个服务对应的输出标签:右键其中一个运行的标签页,选择 Split and Move Right,把两个服务日志做成左右分屏。
我实际这么用过:左边跑 Web API,右边跑后台 Worker,两边日志在同一个 IDE 里并排滚动。哪个服务报错了、哪个服务请求超时了,一眼就能对比出来,比来回切换标签页效率高得多。
5.2 跑单元测试时,把 Tests 窗口和 Run 窗口分开
跑单元测试时,Rider 底部会出现 Tests 窗口,显示测试用例通过/失败的状态。如果你的测试代码还在拼命输出日志,Tests 窗口和 Run 窗口在一块,布局就会很挤。
我的做法是,在测试运行前手动把 Run 标签页拖到右侧停靠,Tests 窗口留在底部。这样左侧是测试结果列表,右侧是测试输出的具体日志。哪个用例挂了,点击跳过去,右侧日志立刻给出对应输出,整个定位链路非常短。
这个方法在调试失败测试时特别好用,尤其当测试涉及大量数据库操作时,日志输出和测试断言的关联性非常强。
5.3 前端、游戏与其他调试场景的延伸思路
不止是 .NET,Rider 在很多跨平台场景下也可以用同样的分窗逻辑。比如调试 Unity 项目时,Rider 通过 Unity Debugger 插件连接 Unity 编辑器,Unity 的 Debug.Log 输出通常显示在控制台,而调试器内部的线程、堆栈、模块事件则显示在 Debug 窗口。把两个窗口拆开,配合 Unity 编辑器本身,布局比默认叠在一起舒服太多。
如果你是前端开发者顺手在用 HBuilderX 的内置浏览器调试,思路也是一样的:浏览器开发者工具里的 Console 面板和 Sources 面板分屏展示,一个看输出一个看代码,交互路径比来回切换短。Rider 的这条分窗思路其实放之四海而皆准,核心就是:把运行时输出和调试器状态分开,让每个信息流都有自己的物理位置。
6. 翻车现场速查表:控制台一锅粥的常见原因
6.1 Debug 输出“消失”了
最典型的现象是:明明在代码里写了Debug.WriteLine,运行后却什么也没打印出来。
原因多半是项目没有启用 DEBUG 编译符号。Rider 调试模式启动会默认使用 Debug 配置,所以你按Shift+F9时大概率能看到输出;但如果用 Release 配置直接运行,Debug.WriteLine会被编译器移除,自然什么也看不到。
解决方法是改用Trace.WriteLine,它对编译符号TRACE敏感,而 Release 配置默认保留了TRACE。或者干脆在启动配置里明确切换成 Debug 构建。排这个坑时,先确认右下角构建配置,再看输出,不要一口咬定是 IDE 的锅。
6.2 中文乱码
在 Windows 环境下跑控制台程序,Console.WriteLine 输出中文时偶尔会乱码。常见原因是项目文件编码和控制台代码页不一致。解决办法是:
- 把 Rider 的全局和项目 File Encoding 统一设置成 UTF-8。
- 如果是在 Windows Terminal 里运行,把活动代码页切到 UTF-8,对应命令是
chcp 65001。 - 不要在代码里手动给 Console 加各种 Encoding 支持代码,先检查 IDE 配置。
这个坑本质上属于环境配置问题,跟 Rider 分不分窗关系不大;但输出一旦乱码,分到哪个窗口里都是乱码,所以建议提前治理。
6.3 日志量大到 IDE 卡顿
控制台疯狂滚屏,IDE 开始掉帧,这是日志爆炸的典型症状。最常见原因不是 IDE 性能差,而是你的代码在循环里放了高频Console.WriteLine,或者框架日志级别被调成了 Debug。
解决思路有三步:
- 先把日志级别调高,比如把
Microsoft.AspNetCore提到 Warning,减少框架输出。 - 在输出窗口点暂停按钮,暂时制动输出滚动,等程序跑一段后按需查看。
- 用 “Clear All” 清屏,别让无用的日志堆积在内存里。
如果日志数量大到影响程序本身的执行性能,说明问题已经不在 IDE 显示层,而是要回到日志框架层面做限流或采样。
6.4 常见问题速查表
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| Debug.WriteLine 没有任何输出 | Release 配置编译,DEBUG 符号不存在 | 改用 Trace.WriteLine,或切到 Debug 配置运行 |
| 控制台中文乱码 | 文件编码与控制台代码页不一致 | 统一为 UTF-8,必要时执行chcp 65001 |
| 窗口里的日志疯狂刷屏 | 日志级别过低,高频输出 | 调高 Logging.LogLevel 为 Warning |
| 异常信息大量出现在 Debug 输出 | 第三方库抛出“故意异常” | 启用 User-unhandled exceptions 等过滤策略 |
| 运行结束太快看不到输出 | 程序立即退出,窗口被关闭 | 检查 Run 配置是否启用了脚本执行后的停留逻辑,或用调试模式加断点 |
最后再分享一套我自己的日常配置方案:Shift+F9启动调试后,右键 Debug 标签页选择 Split and Move Right,让调试输出固定到右侧;appsettings.json里把 Microsoft 框架日志降到 Warning;关键错误输出用 ANSI 红色标识;临时观察变量和条件判断用断点日志代替Console.WriteLine。这套组合拳配合下来,控制台基本不会再出现“一锅粥”的局面。
分窗口这个习惯,我大概花了一周左右才真正养成。一开始总是嫌麻烦,后来越用越觉得值。如果你跟我一样天天泡在 Rider 里调试,不妨今天就试试把 Run 和 Debug 拆开,相信几分钟之后你就不会再想点回去了。