Multithreading Gtk#多线程时窗口移动冻结
我目前正在尝试在Windows下使用多线程Gtk 除了这个使应用程序无法使用的小错误之外,一切正常:你不能移动或调整应用程序的大小,因为它会冻结 这看起来像是Gtk中的一个潜在错误 下面是一个重现问题的示例:一个简单的窗口、一个标签和一个按钮。标签和按钮不是必需的,但提供证明Gtk正常运行的证据。每当我移动窗户,最大化它,它就会停止Multithreading Gtk#多线程时窗口移动冻结,multithreading,gtk#,Multithreading,Gtk#,我目前正在尝试在Windows下使用多线程Gtk 除了这个使应用程序无法使用的小错误之外,一切正常:你不能移动或调整应用程序的大小,因为它会冻结 这看起来像是Gtk中的一个潜在错误 下面是一个重现问题的示例:一个简单的窗口、一个标签和一个按钮。标签和按钮不是必需的,但提供证明Gtk正常运行的证据。每当我移动窗户,最大化它,它就会停止 using System; using Gtk; namespace FreezingWindow { class MainClass {
using System;
using Gtk;
namespace FreezingWindow
{
class MainClass
{
public static void Main (string[] args)
{
if (GLib.Thread.Supported) {
GLib.Thread.Init ();
}
Gdk.Threads.Init ();
Gdk.Threads.Enter ();
Application.Init ();
Window win = new Window ("test");
var box = new VBox ();
var label = new Label ("Test");
box.PackStart (label);
var btn = new Button ("Test");
btn.Clicked += delegate(object sender, EventArgs e) {
label.Text = DateTime.Now.ToString();
};
box.PackStart (btn);
win.Add (box);
win.ShowAll ();
Application.Run ();
Gdk.Threads.Leave ();
}
}
}
下面是我如何处理多线程+GUI更改的方法。我完全避免使用您使用的线程方法,并坚持使用System.threading命名空间。它使用响应性GUI创建真正的多线程应用程序。(另外,我通常创建一个单独的类,该类严格适用于表单及其所有方法。) 利用Application.Invoke更新GUI
private void DoThreadStuff()
{
// Stuff that is processing on the separate thread.
// Need to use Application.Invoke if updating the GUI from the thread.
Application.Invoke(delegate {
label.Text = string.Format("Did stuff at {0}", DateTime.Now);
});
}
private void InvokeMethod(System.Action methodName)
{
Application.Invoke(delegate {
methodName();
});
}
我喜欢使用的另一个方法是创建一个通用方法,该方法接受我们需要在Application.Invoke下执行的方法名
private void DoThreadStuff()
{
// Stuff that is processing on the separate thread.
// Need to use Application.Invoke if updating the GUI from the thread.
Application.Invoke(delegate {
label.Text = string.Format("Did stuff at {0}", DateTime.Now);
});
}
private void InvokeMethod(System.Action methodName)
{
Application.Invoke(delegate {
methodName();
});
}
谢谢你的信息。然而,我想使用多线程的主要原因是为了加速Cairo绘图,这是用这种方法无法实现的。我个人不知道有什么方法可以真正做你想做的事。也许有办法,但我不知道。我认为所有核心内的重画都发生在同一个线程上,或者疯狂开始发生。再说一次,我可能大错特错,但这是我的理解。我很想知道是否有一些方法可以做到这一点,而不必分叉GTK,也不必在源代码中创建自己的多线程绘图版本。到目前为止,我发现GTK 2基本上应该是多线程的,但如果有我所描述的bug,它是没有用的。然而,对于GTK3,他们似乎已经完全消除了多线程意识,因此我们别无选择,只能使用您描述的方法。。。