跳到主要内容

插件内部:MonitorService 事件(不是 VS Code 发来的)

和 VS Code 事件的区别​

VS Code → 插件插件内部(本节)
例子onDidChangeConfigurationmonitorService.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 怎么更新
侧栏打开 / 点 Playstart()定时 fire 快照 → 上面订阅回调
侧栏关闭 / 点 Pausestop()不再 fire,树/状态栏保持最后值
点刷新requestNow()立刻 fire 一次快照
改 refreshIntervalMsupdateInterval()改变 fire 的频率

配置怎么读: 04-configuration.md
VS Code 发来的可见性事件: 02-events.md