2

我是 GTK# 的新手(以及一般的桌面开发)。我在 MonoDevelop 中设置了一个小应用程序,只有一个进度条和一个按钮来测试它。问题是在我的假进程完成之前它不会更新。我看到其他帖子说 Application.Invoke() 根据此链接Mono Best Practices是必需的。但是我仍然无法让这件事起作用,这可能是我理解的一个根本缺陷。这是我的代码:

using System;
using Gtk;
using System.Diagnostics;
using System.Threading;

public partial class MainWindow: Gtk.Window
{   
    public MainWindow (): base (Gtk.WindowType.Toplevel)
    {
        Build ();
    }

    protected void OnDeleteEvent (object sender, DeleteEventArgs a)
    {
        Application.Quit ();
        a.RetVal = true;
    }

    protected void OnOkClicked (object sender, EventArgs e)
    {
        for (int i = 0; i < 100; i++){
            Thread.Sleep(1000);
            Application.Invoke (delegate {
                progressbar1.Fraction = i / 100.0;
            });
        }
    }
}
4

2 回答 2

2

可能发生的情况是处理进度条视觉更新的事件(信号)的优先级较低,因此尽管发送了它们,但进度条视觉显示不会更新,而只会在关键部分结束时更新在代码中。

您也可以通过强制处理信号来绕过它。例如:

progressbar1.GdkWindow.ProcessUpdates (true); // Request visual update
while(Application.EventsPending()) Application.RunIteration(true); // Process any messages waiting in the Application Message Loop

希望有帮助。

于 2012-11-30T14:44:06.877 回答
0

我在Mono Responsive Applications找到了一个关于 Application.Invoke 的示例,它帮助我弄清楚我需要做什么。这是我的代码的更新版本:

using System;
using Gtk;
using System.Threading;

public partial class MainWindow: Gtk.Window
{   
    public MainWindow (): base (Gtk.WindowType.Toplevel)
    {
        Build ();
    }

    protected void OnDeleteEvent (object sender, DeleteEventArgs a)
    {
        Application.Quit ();
        a.RetVal = true;
    }

    protected void OnOkClicked (object sender, EventArgs e)
    {
        Thread thr = new Thread (new ThreadStart (ThreadRoutine));
        thr.Start ();
    }

    void ThreadRoutine ()
    {
        for (int i = 0; i < 100; i++)
        {
            LargeComputation ();
            Application.Invoke (delegate {
                progressbar1.Fraction = i / 100.0;
            });
        }
    }

    void LargeComputation ()
    {
        // lots of processing here
        Thread.Sleep(1000);
    }
}
于 2012-11-30T07:25:28.917 回答