Go/gotk3中能否在glib.TimeoutSecondsAdd循环内部修改超时间隔?
在Go/gotk3的glib.Timeout循环中动态调整超时间隔的实现方式
直接修改已创建的glib.Timeout定时器间隔是做不到的,因为glib.TimeoutSecondsAdd生成的定时器间隔是固定的。但可以通过销毁旧定时器+创建新定时器的方式实现动态调整,完全满足你根据内存占用调整更新频率的需求,具体方案如下:
核心思路
- 保存定时器的源ID:调用
glib.TimeoutSecondsAdd会返回一个glib.SourceHandle类型的ID,将其存在全局或闭包可访问的变量中,用于后续销毁操作。 - 在回调内部按条件处理:
- 内存占用过高时:先销毁当前定时器,再创建一个间隔更长的新定时器,更新源ID变量。
- 需要停止更新时:直接销毁定时器,回调返回
false(返回false本身也会触发定时器自动停止,可结合使用)。
示例代码
import ( "github.com/gotk3/gotk3/glib" // 引入你的其他依赖包 ) var timeoutHandle glib.SourceHandle // 初始化定时器,设置初始间隔(比如1秒) func initStatsUpdater() { timeoutHandle = glib.TimeoutSecondsAdd(1, updateDataRate) } func updateDataRate() bool { // 1. 获取当前内存占用(替换成你实际的内存检测逻辑) currentMemUsage := getCurrentMemoryUsage() // 2. 根据内存情况调整定时器 const highMemThreshold = 80 // 假设内存占用超过80%为过高 const stopMemThreshold = 95 // 超过95%停止更新 if currentMemUsage > highMemThreshold { // 内存过高,销毁旧定时器,创建5秒间隔的新定时器 glib.SourceRemove(timeoutHandle) timeoutHandle = glib.TimeoutSecondsAdd(5, updateDataRate) return true // 旧定时器已移除,返回true不影响新定时器运行 } else if currentMemUsage > stopMemThreshold { // 达到停止条件,销毁定时器并返回false终止循环 glib.SourceRemove(timeoutHandle) return false } // 3. 执行界面数据速率更新逻辑 refreshDataRateUI() // 正常情况返回true,保持当前定时器运行 return true }
注意事项
- 确保源ID变量在回调中可访问,GTK的回调均在主线程执行,无需额外处理并发锁。
- 销毁定时器时确认ID有效,避免重复调用
glib.SourceRemove引发错误。 - 回调返回
true会让当前定时器持续运行,返回false会自动销毁当前定时器,需结合手动销毁操作配合使用。
内容的提问来源于stack exchange,提问作者Hoodoo
相关产品推荐
相关产品推荐

