Golang Walk 通过 Goroutine 处理长时间运行的任务,避免界面卡死

更新日期: 2025-07-31 阅读次数: 603 字数: 621 分类: golang

继续使用 Golang Walk 开发批量生成图片的 Windows 桌面客户端。 但是,要一次性生成几百张图片时,界面会卡死,无法响应用户操作。😅

哈哈,感觉非常像 Android 开发中的 ANR(Application Not Responding)问题。估计也是新开一个类似 kotlin 的协程来处理长时间运行的任务。 对于 Golang 来说就是使用 Goroutine 来处理长时间运行的任务。

ANR 问题

Golang Walk 对于长时间运行的任务,点击按钮后,如何保证界面不会卡死,而且能实时更新 textedit 中的内容呢?

解决方案:

  1. 使用 Goroutine:将长时间运行的任务放入 Goroutine 中执行,这样就不会阻塞主线程,从而避免界面卡死。

  2. 使用 Walk 的 Synchronize 方法:在 Goroutine 中更新 UI 时,必须使用 Walk 的 Synchronize 方法,以确保在主线程中执行 UI 更新操作。

  3. 定期更新进度:在长时间运行的任务中,可以定期更新进度信息到 textedit 中,以便用户了解当前进度。

以下是一个示例代码片段,演示如何在点击按钮后启动一个 Goroutine 来处理长时间运行的任务,并实时更新 UI:

go func() {
    // 在这里执行长时间运行的任务
    for i := 0; i < 100; i++ {
        time.Sleep(100 * time.Millisecond) // 模拟耗时操作
        outTextEdit.Synchronize(func() {
            outTextEdit.AppendText(fmt.Sprintf("当前进度: %d%%\r\n", i+1))
        })
    }
}()

这里 go 关键字用于启动一个新的 Goroutine。

Synchronize 方法的作用

Synchronize enqueues func f to be called some time later by the main goroutine from inside a message loop.

func (wb *WindowBase) Synchronize(f func()) {
	wb.group.Synchronize(f)

	win.PostMessage(wb.hWnd, syncMsgId, 0, 0)
}

Synchronize 方法的作用是将传入的函数 f 安排在主 Goroutine 中执行。这对于更新 UI 非常重要,因为 Walk 的 UI 元素只能在主 Goroutine 中安全地访问和修改。

这类似于 Android 开发中的 UI 线程的概念。

关于作者 🌱

我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式

tags: golang walk