【发布时间】:2016-09-15 02:09:56
【问题描述】:
当我使用此页面中的任何代码而不进行任何修改时:https://wiki.gnome.org/Projects/Vala/AsyncSamples
我总是得到:
warning: ‘g_simple_async_result_new’ is deprecated: Use 'g_task_new' instead.
所以我继续建议使用GTask。但是,当我尝试在 Vala 中使用 GLib.Task 时,我只是在声明一个任务时遇到了困难。因此,我没有在我自己的代码中使用来自 GIO 的异步,因为它已被弃用,我尝试使用 GLib.Task 来简单地使用 for 循环中的数字更新 Gtk 按钮的标签,这样代码如下所示:
using Gtk;
Button button;
public static int main (string[] args) {
Gtk.init (ref args);
var window = new Window ();
window.title = "Count without blocking the UI";
window.border_width = 10;
window.window_position = WindowPosition.CENTER;
window.set_default_size (350, 70);
window.destroy.connect (Gtk.main_quit);
button = new Button.with_label ("Start counting");
button.clicked.connect (() => {
GLib.Task task = new GLib.Task(button, new Cancellable());
});
window.add (button);
window.show_all ();
Gtk.main ();
return 0;
}
void count(){
for(int i = 0; i < 10000; i++){
button.label = i.to_string();
}
}
但编译时我得到:error: ‘_data_’ undeclared (first use in this function)
_tmp3_ = g_task_new_finish (_data_->_res_);
第 15 行是导致编译器抛出该错误的原因。它来自vala编译器生成的C代码。
我发现的主要问题是 Vala 中的 GTask 构造函数签名与 C 不同。因此,我无法重新创建此处找到的代码:GUI becomes unresponsive after clicking the button using GTK+ in C
因为对于初学者来说,我不允许将两个以上的参数传递给 GLib.Task 对象构造函数。 Task 对象的构造函数在每种语言中都不同。 Vala中GLib.Task的构造函数可以在here找到。
因此我的问题是:
有没有关于如何在 Vala 中使用 GLib 任务 (GTask) 来执行更新 UI 而不阻塞它的操作的示例?如果没有,是否有另一种方法来更新 UI 而不会阻止它?一种不被弃用的方式?
谢谢。
P.S:我已经尝试过 GLib.Thread、GLib.ThreadPool 和 GLib.Idle。它们都在 for 循环中阻塞了 UI。 GLib.Idle 不会完全阻塞 UI,但它会呈现错误,因为在循环运行时响应用户输入变得非常缓慢。
【问题讨论】:
-
尽快更新 UI 几乎肯定会在单线程模型中阻止它。您可以进行更重要的计算,也可以在我的回答中的循环中使用
GLib.Timeout。 -
我不太确定我是否了解那里发生的情况以及该补丁的功效。我有一个较新版本的 glib: 2.48.1 并且无论在我的代码中使用 --target-glib=2.48.1 和 valac,我仍然会收到警告。我认为临时解决方案不起作用。
标签: multithreading gtk3 vala