我目前正在尝试在Windows下使用多线程Gtk#。
一切正常,除了这个使应用程序无法使用的小错误:你无法移动或调整应用程序的大小,因为它会冻结。
它看起来像Gtk中的潜在错误#。
这是一个重现问题的示例:一个简单的窗口,一个标签和一个按钮。标签和按钮不是必需的,但提供Gtk正常运行的证据。每当我移动窗户时,最大化它,它就会失速。
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 ();
}
}
}
答案 0 :(得分:0)
以下是我如何使用多线程+ GUI更改。我完全避免使用您使用的线程方法并严格使用System.Threading命名空间。它使用响应式GUI创建真正的多线程应用程序。 (另外,我通常会创建一个严格用于表单及其所有方法的单独类。)
// Create the thread and tell it to execute the DoThreadStuff method.
Thread thread = new Thread(new ThreadStart(DoThreadStuff));
thread.Start();
使用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);
});
}
我喜欢使用的另一种方法是创建一个通用方法,该方法接受我们需要在Application.Invoke下执行的方法名称。
private void InvokeMethod(System.Action methodName)
{
Application.Invoke(delegate {
methodName();
});
}