为了账号安全,请及时绑定邮箱和手机立即绑定

立即重新启动 goroutine 的最佳方法?

立即重新启动 goroutine 的最佳方法?

Go
繁星淼淼 2022-10-24 16:24:02
我写了以下函数:func (timer *Timer) ticker() {    for timer.time >= 0 {        select {        case <-timer.stopFlag:            return        default:            timer.DataChannel <- timer.timeToString()            timer.time--            time.Sleep(time.Second)        }    }}func startLabelUpdateListener(timer *t.Timer, w *app.Window, label *string) {    for time := range timer.DataChannel {        *label = time        w.Invalidate()    }}这是一个简单的计时器,它连接到一个标签,每当 DataChanel 上有更新时,该标签就会更新。它们都被称为 goroutines。现在有没有办法立即停止自动收报机并再次调用它,就在之后?假设我想重新启动这个计时器。我希望它立即停止,并启动另一个ticker goroutine 来接管。我尝试了以下方法,但遇到了一些问题:timer.stopFlag <- truego timer.ticker()...这样做的问题是它不是即时的,因为我正在使用 time.Sleep() go 等待直到睡眠结束,这对于响应性来说并不是很好,因为这会引入 UI 延迟。手动更新标签dataChannel <- "some_time"意味着如果用户在 0.9 秒睡眠后单击重新启动按钮,则计时器在 1.9 秒内不会改变。close(timer.stopFlag)timer.stopFlag = make(chan bool)go timer.ticker()...这很好而且即时(通过睡眠或至少看起来是这样)但问题是,通道现在已关闭并重新打开它以某种方式阻止前一个 goroutine 终止并按下重新启动按钮几次堆叠 goroutine我还考虑过将 time.sleep 设置为 0.1 秒,并且每 10 次迭代减少一次时间,但这感觉有点笨拙。有更好的解决方案吗?
查看完整描述

1 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

使用 time.Ticker而不是睡觉。

func (timer *Timer) ticker() {

    // Send the first.

    timer.DataChannel <- timer.timeToString()

    timer.time--


    // Loop sending each second. 

    t := time.NewTicker(time.Second)

    defer t.Stop()

    for timer.time >= 0 {

        select {

        case <-timer.stopFlag:

            return

        case <-t.C:

            timer.DataChannel <- timer.timeToString()

            timer.time--

        }

    }

}



查看完整回答
反对 回复 2022-10-24
  • 1 回答
  • 0 关注
  • 96 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号