6

重複の可能性:
別のスレッドからプログレスバーを更新する

私のプログラムでは、GUI以外の機能を別のクラスに分離し、GUIに関連するものをメインクラスに残したいと思いました。ただし、workerクラスのworkerメソッドの1つがジョブを実行しているときに、進行状況バーを更新する際に問題が発生します。ここでマルチスレッドを使用する必要があることはわかっていますが、その方法がわかりません。簡単なことが足りないかもしれませんが、それに関する情報を探すと、ほとんどのチュートリアルで細目について説明しているように見えますが、全体像をうまく説明していません。私はinvokeコマンドとdelegateコマンドが何であるかを部分的に理解していますが、それらがどのように相互作用するかは本当に理解していません。

以下は私がやりたいことの簡略版です。これを変更してプログレスバーを更新し、ウィンドウの応答性と再描画を維持するにはどうすればよいですか?

メインフォームクラス:

public partial class Form1 : Form
{
    time_waster thing = new time_waster();

    public Form1()
    {
        InitializeComponent();
        progressBar1.Minimum = 0;
        progressBar1.Maximum = 100;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        thing.something_that_takes_a_while();
    }
}

個別のワーカークラス:class time_waster {public time_waster(){}

    public void something_that_takes_a_while()
    {
        int delay = 200;
        for (int i = 0; i < 100; i++)
        {
            Thread.Sleep(delay);
            //appropriate code to update the progress bar for each iteration of the for loop.
        }
    }
}
4

3 に答える 3

7

.NETには、イベントのバックグラウンド スレッドの進行状況を報告するためのメソッドを提供するBackgroundWorkerというクラスが含まれています。このイベントは、BackgroundWorker を作成したスレッド (通常は UI スレッド) で自動的に呼び出されます。

その「ProgressChanged」イベントをサブスクライブし、そのイベント ハンドラーの進行状況バーを更新します。公式の MSDN ドキュメントには、いくつかのサンプル コードが記載されています。

于 2012-05-24T00:56:06.560 に答える
5
MethodInvoker mi = new MethodInvoker(() => progressBar.Value= newProgressValue);
if (progressBar.InvokeRequired)
{
    progressBar.Invoke(mi);
}
else
{
    mi.Invoke();
}

このコードは、時間のかかるタスクに属します。見る:

  1. 呼び出し必須
  2. 呼び出す
  3. デリゲート

ラムダは、クラスのメソッドとして、またはそれらをサポートする言語の生の関数としてではなく、インラインで宣言される関数 (またはメソッド) の単なる派手な言葉です。名前付き変数に割り当てない場合は「匿名」です。それらは必要な変数を「キャプチャ」し、理解していないと少し奇妙な動作をする可能性があるため、注意してください。

ラムダの構文は非常に簡単です。ラムダにパラメーターを追加するために括弧に物を入れる() => someValue;のとほとんど同じです。public void SomeMethod() { return someValue; }パラメータが 1 つしかない場合は、かっこをスキップしてかまいません。

于 2012-05-23T21:37:23.927 に答える
4
   static main()
    {
         Thread th = new Thread(calling_function);
         th.start();  
    }


    calling_function()
    {
        //do your work;
        MethodInvoker m = new MethodInvoker( ()=> progressbar.Progress=value);
        progressbar.Invoke(m);
    }
于 2012-05-23T21:40:31.633 に答える