0

作業中にさまざまなアイコンで進行状況を示すプログラムがあります。btnApply ボタンを押すとプロセスが開始されます。

ManualResetEvent[] wait; 

    private void btnApply_Click(object sender, EventArgs e)
    { 
        wait = new ManualResetEvent[1]; 
        wait[0] = new ManualResetEvent(false); 
        ThreadPool.QueueUserWorkItem(new WaitCallback(doApply), 0); 
        WaitHandle.WaitAny(wait); 
        btnApply.Text = "Done!"; 
    }

    private void doApply(object dummy) 
    { 
        for (int i = 0; i < 14; i++) 
        { 
            setPic(i, bmTODO); 
        } 
        // do something 
        for (int i = 0; i < 14; i++) 
        { 
            setPic(i, bmWORK); 
            // do something 
            setPic(i, bmOK); 
        } 
    } 

    public void setPic(int i, Image img) 
    { 
        switch (i) 
        { 
            case 0: pictureBox1.Image = img; break; 
            case 1: pictureBox2.Image = img; break; 
            case 2: pictureBox3.Image = img; break; 
            case 3: pictureBox4.Image = img; break; 
            case 4: pictureBox5.Image = img; break; 
            case 5: pictureBox6.Image = img; break; 
            case 6: pictureBox7.Image = img; break; 
            case 7: pictureBox8.Image = img; break; 
            case 8: pictureBox9.Image = img; break; 
            case 9: pictureBox10.Image = img; break; 
            case 10: pictureBox11.Image = img; break; 
            case 11: pictureBox12.Image = img; break; 
            case 12: pictureBox13.Image = img; break; 
            case 13: pictureBox14.Image = img; break; 
            default: break; 
        } 
    }

Win7 と 2 プロセッサでは、これは「本来あるべき」動作をします。
しかし、XP ではタスクを切り替える必要がありますが、この特別なコードではどうすればよいのでしょうか? doApply で各ピクチャボックスを指定したくありません。

私もデリゲートで試しました:

public delegate void setPicDelegate(int i, Image img);

しかし、満足のいく結果はありませんでした。プログラムがハングするか、アイコンが最後に表示されます。

私に何ができる?

4

1 に答える 1

1

問題は、次のように UI スレッドをブロックしていることですWaitHandle.WaitAny(wait);btnApply_ClickUI スレッドが新しいアクションを処理できるようにするには、実行時間の長いタスクが終了する前にメソッドを終了できるようにする必要があります。

UI コンテキストで長時間実行されるタスクをモデル化する簡単な方法は、 を使用するBackgroundWorkerことです。これにより、多くの問題が抽象化されます。

イベント ハンドラーで実行時間の長い作業をすべて実行し、DoWorkイベントを使用して作業が完了したら UI を更新しますRunWorkerCompleted。そのイベント ハンドラーは UI スレッドで実行されます。このクラスは、結果を UI に渡したり、進行状況の変更情報を UI で処理したりすることもサポートしています。

于 2013-01-24T16:30:25.257 に答える