VS Code接收大量日志时短暂无响应/崩溃的代码修复咨询
解决VS Code日志大量输出时无响应/崩溃的问题
原代码的核心问题在于高频触发VS Code日志输出API,以及全局变量引发的潜在数据混乱,导致主线程被阻塞。以下是修复后的代码:
class TestGetLog { // 改用类静态属性存储未完成的日志片段,避免全局污染 private static recordEndData = ''; // 节流定时器ID,用于批量输出日志 private static logTimer: NodeJS.Timeout | null = null; // 批量日志缓存 private static logBuffer: string[] = []; static createActiveDatalog(logger: LogOutputChannel, context: ExtensionContext): void { const connect = createConnection({ host: '127.0.0.1', port: 20001 }, () => { logger.show(); const sendPorts = [20001, 20003]; if (connect.localPort && sendPorts.includes(connect.localPort)) { connect.destroy(); // 用setTimeout避免递归调用导致栈溢出 setTimeout(() => TestGetLog.createActiveDatalog(logger, context), 100); return; } }); connect.on('data', (data) => { const logData = TestGetLog.recordEndData + String(data); const lines = logData.split('\n'); if (logData.endsWith('\n')) { TestGetLog.recordEndData = ''; // 将完整行加入缓存 TestGetLog.logBuffer.push(...lines.slice(0, lines.length - 1)); } else { TestGetLog.recordEndData = lines[lines.length - 1]; // 将完整行加入缓存 TestGetLog.logBuffer.push(...lines.slice(0, lines.length - 1)); } // 启动节流定时器,每隔200ms批量输出一次日志 TestGetLog.flushLogs(logger); }); connect.on('close', () => { // 连接关闭时清空剩余缓存 if (TestGetLog.logBuffer.length > 0) { logger.info(TestGetLog.logBuffer.join('\n')); TestGetLog.logBuffer = []; } // 输出剩余的未完成片段 if (TestGetLog.recordEndData) { logger.info(TestGetLog.recordEndData); TestGetLog.recordEndData = ''; } if (TestGetLog.logTimer) { clearTimeout(TestGetLog.logTimer); TestGetLog.logTimer = null; } }); // 处理连接错误,避免未捕获异常 connect.on('error', (err) => { logger.error(`日志连接出错: ${err.message}`); connect.destroy(); }); // 将连接实例存入上下文,防止被GC回收 context.subscriptions.push({ dispose: () => { connect.destroy(); if (TestGetLog.logTimer) clearTimeout(TestGetLog.logTimer); } }); } private static flushLogs(logger: LogOutputChannel): void { if (TestGetLog.logTimer) return; TestGetLog.logTimer = setTimeout(() => { if (TestGetLog.logBuffer.length === 0) { TestGetLog.logTimer = null; return; } // 批量输出缓存的日志 logger.info(TestGetLog.logBuffer.join('\n')); TestGetLog.logBuffer = []; TestGetLog.logTimer = null; }, 200); // 可根据需求调整间隔时间 } }
关键修改点说明
- 移除全局变量:将
recordEndData改为类的静态私有属性,避免多次调用方法时的数据交叉污染。 - 批量日志输出:增加日志缓存和节流定时器,将高频的
logger.info调用合并为批量调用,减少VS Code主线程的UI更新压力,避免卡顿。 - 修复拼写错误:修正
post→port、reocrdEndData→recordEndData的拼写问题。 - 优化连接逻辑:用
setTimeout代替直接递归调用createActiveDatalog,避免栈溢出风险。 - 完善资源清理:在连接关闭、插件销毁时清空缓存、关闭定时器、销毁连接,防止内存泄漏。
- 添加错误处理:捕获连接错误并输出日志,避免未处理异常导致插件崩溃。
内容的提问来源于stack exchange,提问作者aizhixin
相关产品推荐
相关产品推荐

