插件内部:MonitorService 事件(不是 VS Code 发来的)
和 VS Code 事件的区别
| VS Code → 插件 | 插件内部(本节) | |
|---|---|---|
| 例子 | onDidChangeConfiguration | monitorService.onDidChangeSnapshot |
| 发生位置 | 跨进程,VS Code 触发 | 同一 Extension Host 进程里 |
| 谁会刷新界面 | 你在回调里调 VS Code API | 订阅者里调 TreeProvider / StatusBar 等 |
模式一样:都是 EventEmitter + .event 订阅 + .fire(数据),但 fire 快照不会自动更新树,必须在回调里调用 treeProvider.update 和 statusBar.update(内部再 fire 树或改状态栏)。
MonitorService 里的事件 API
文件:src/monitorService.ts
定义
private readonly _onDidChangeSnapshot =
new vscode.EventEmitter<MonitorSnapshot>();
private readonly _onDidError = new vscode.EventEmitter<string>();
/** 快照更新事件,所有 UI 组件都订阅它 */
readonly onDidChangeSnapshot = this._onDidChangeSnapshot.event;
/** 采集失败事件,用于把错误传递给 Webview 或日志 */
readonly onDidError = this._onDidError.event;
onDidChangeSnapshot:一次硬件采集成功,得到MonitorSnapshot时触发。onDidError:采集失败,带错误消息(Webview 面板也会订阅;Tree/StatusBar 主要用快照)。
何时 fire
采集成功后(节选逻辑):
this._onDidChangeSnapshot.fire(snapshot);
失败时:
this._onDidError.fire(message);
谁启动采集:start() / requestNow() / 侧栏可见时的 syncMonitoringWithSidebarVisibility(见 extension.ts),最终都会走到内部的 collectAndSchedule 一类逻辑。
在 extension.ts 里订阅快照(驱动非 Webview UI)
const treeProvider = new HardwareTreeProvider();
const statusBar = new StatusBarController();
const alerter = new ThresholdAlerter();
...
monitorService.onDidChangeSnapshot(
(snapshot) => {
treeProvider.update(snapshot);
statusBar.update(snapshot);
alerter.update(snapshot);
},
undefined,
context.subscriptions,
);
通信链(仅 Extension Host 内 + 最后一步到 VS Code UI):
MonitorService.collect…
→ _onDidChangeSnapshot.fire(snapshot)
→ 上面这个回调
├─ HardwareTreeProvider.update
│ → setContext(hasData) + onDidChangeTreeData.fire()
│ → VS Code 树视图刷新(见 03-ui-providers.md)
├─ StatusBarController.update
│ → item.text / show()
│ → VS Code 状态栏刷新
└─ ThresholdAlerter.update
→ getConfiguration 读阈值 → 可能 showWarningMessage
HardwareTreeProvider 的内部事件(连到 VS Code 树)
文件:src/hardwareTreeProvider.ts
TreeProvider 自己也有一套 Emitter,但 听众是 VS Code(注册 TreeView 时绑定的):
private readonly _onDidChangeTreeData = new vscode.EventEmitter<...>();
readonly onDidChangeTreeData = this._onDidChangeTreeData.event;
update(snapshot) 保存快照后 this._onDidChangeTreeData.fire(),VS Code 才会再次调用 getChildren 把 CPU、内存等节点画出来。
数据流:
MonitorService.onDidChangeSnapshot
→ treeProvider.update(snapshot) // 插件内部:写 snapshot 变量
→ onDidChangeTreeData.fire() // 插件 → VS Code:请重绘树
→ VS Code 调用 getChildren(...) // VS Code → 插件:拉取节点
Webview 也用同一份 MonitorService(略提)
dashboardPanel.ts / webview2Panel.ts 里同样订阅:
monitorService.onDidChangeSnapshot→ 通过 webview 的 postMessage 发给前端(不属于 VS Code 原生 Tree/StatusBar 通信)。
侧边栏树和状态栏 不经过 Webview,只经过 extension.ts 里这一段订阅。
和命令、配置的关系
| 用户操作 | 影响 MonitorService | 之后 UI 怎么更新 |
|---|---|---|
| 侧栏打开 / 点 Play | start() | 定时 fire 快照 → 上面订阅回调 |
| 侧栏关闭 / 点 Pause | stop() | 不再 fire,树/状态栏保持最后值 |
| 点刷新 | requestNow() | 立刻 fire 一次快照 |
| 改 refreshIntervalMs | updateInterval() | 改变 fire 的频率 |
配置怎么读: 04-configuration.md
VS Code 发来的可见性事件: 02-events.md