使用 Rust 构建 GNOME 应用,第六部分:获取 Feed
本文详细介绍了如何在不冻结用户界面的情况下将网络取物集成到 GNOME 应用中。之前的步骤设置了一个侧边栏显示订阅源名称,但选择订阅源只更新显示文本,而不会更新内容。在输入选择的信号处理器中尝试直接网络取用,作为一种简单的解决方案,会导致整个应用窗口在取指过程中冻结。这次卡死是因为GTK的主循环运行在单一线程上,阻断它会导致界面更新和响应性都不行。核心问题在于 GTK/GObject 类型不具线程安全,意味着它们无法直接从后台线程中操作。该解决方案涉及运行两个不同的执行程序:GTK 的 GLib 主循环用于 UI 任务,以及用于 I/O 绑定操作(如网络请求)的 Tokio 运行时。这些执行器严格分开,遵循GLib循环永不阻塞的规则,Tokio也绝不直接接触GTK/GObject类型。它们之间的通信发生在一个“缝隙”,未来在GLib上下文中可以等待Tokio结果,然后以明值安全返回主上下文。为此,应用程序添加了 Tokio 和“reqwest”依赖关系。Tokio 运行时在 GTK 应用程序启动前的“main”中构建一次,其句柄存储在 “GazetteApplication” 结构中。创建了一个新的“src/fetch.rs”模块,包含异步“fetch_feed”函数。该函数在 Tokio 运行时使用 'reqwest' 来下载和解析 RSS/Atom 订阅源,返回一个 'Vec<FeedItem>' 结构。这个“FeedItem”是一个普通的Rust结构体,而不是GObject,确保它可以安全地传回GLib主线程而不违反线程安全规则。