Gtk#窗口移动在多线程

时间:2015-05-03 16:58:34

标签: multithreading gtk#

我目前正在尝试在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 ();
        }
    }
}

1 个答案:

答案 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();
    });
}