0

メインクラス(メインスレッド)で生成されたカスタムプログレスバーを備えたカスタムフォームがあります。次に、スレッドを生成し、ThreadStart 関数を送信します。このスレッド開始関数は、カスタム コントロールのプログレス バーを更新する必要がありますが、そうではありません。

class MyClass
{
......
//Custom form with progress bar
public CustomFormWithProgressBar statusScreen = new CustomFormWithProgressBar(0);
//thread to use
private Thread myThread;

.....
//Linked to a button to trigger the update procedure.
void ButtonPressEvent(.......)
{
    //create a sub thread to run the work and handle the UI updates to the progress bar
    myThread = new Thread(new ThreadStart(ThreadFunction));
    myThread.Start();
}
.....
//The function that gets called when the thread runs
public void ThreadFunction()
{
    //MyThreadClass myThreadClassObject = new MyThreadClass(this);
    //myThreadClassObject.Run();
    statusScreen.ShowStatusScreen();

    for (int i = 0; i < 100; i++ )
    {
        statusScreen .SetProgressPercentage(i);
        Thread.Sleep(20);
    }
    statusScreen.CloseStatusScreen();
}

これで、私の statusScreen フォームはただ座って何もしません。更新は行われません。しかし、サブスレッドが実際に作成されていることを確認し、ThreadFunction にいる間、新しいスレッドで実行しています。これは、Visual Studio のスレッド ウィンドウで確認しました。

ステータス画面の進捗率の更新が表示されないのはなぜですか? 進行状況画面に新しい値をプッシュしてライブで表示するように更新を取得するにはどうすればよいですか?

ステータス画面関数に送信される整数値は、完了のパーセンテージを表すことに注意してください。Thread.Sleep は、発生した場合に更新を確認するためのものです。

これは再描画の問題ではないことに注意してください。進行状況パーセンテージがカスタム進行状況バーに渡されたときに Invalidate を呼び出します

4

2 に答える 2

2

別のスレッドからコントロールを更新することはできません。

正しい方法 - あなたの目的のために BackgroundWorker を使用しています。別の方法 (ほぼ正しい方法) - Control.Invoke メソッドを使用します。もう 1 つのほぼ正しい方法 - SynchronizationContext を使用します。

ただし、権力の暗黒面を選択して、CheckForIllegalCrossThreadCalls (Control クラスの静的プロパティ) を使用し、それを false に設定することもできます。

于 2013-05-02T20:30:55.137 に答える