2

私はGTK#(およびデスクトップ開発全般)が初めてです。プログレスバーとそれをテストするためのボタンだけを使用して、MonoDevelop で小さなアプリをセットアップしました。問題は、偽のプロセスが完了するまで更新されないことです。このリンクMono Best Practicesに従って Application.Invoke() が必要であると言っている他の投稿を見ました。しかし、私はまだこれを機能させることができません。おそらく私の理解の根本的な欠陥です。これが私のコードです:

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 に答える