3

次のコードは、UI スレッドをハングさせます。

    private void button1_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(Func);
        t.Start();
    }

    private void Func()
    {
        this.Invoke((Action)(() =>
        {
            while (true);
        }));
    }

Func()ボタンをクリックするたびにUIスレッドがフリーズすることなく、別の作業スレッドで呼び出したいと思います。

最善の回避策は何ですか?

4

2 に答える 2

3

あなたのコードでwhile(true)は、UI スレッドで実行されています。これが UI をブロックする理由です。

メソッドwhile(true)の外にInvoke出すため、UI を変更するときはいつでも、UI を変更するコードのブロックを内部に配置しますInvoke

private void button1_Click(object sender, EventArgs e)
{
    Thread t = new Thread(Func);
    t.Start();
}

private void Func()
{
    while(true)
    {
       this.Invoke((Action)(() =>
        {
            textBox.Text = "abc";
        }));
    } 
}
于 2012-10-25T05:57:42.960 に答える
2

Func() コードは非 UI スレッドで実行されます。ただし、this.Invokeその後、UI スレッドでアクションを実行します。

次のようなことを試してください:

void Func()
{
     // Do some work.

     // Update the UI (must be on UI thread)
     this.Invoke(Action) (() =>
     {
        // Update the UI.
     }));
 }

メソッドを使ったほうがいいかもしれませんBeginInvoke。このようにして、UI スレッドがアクションを実行するのを非 UI スレッドが待機することはありません。

また、例外をキャッチしたり、進行状況を報告したりするロジックもありません。BackgroundWorkerクラスを見ることをお勧めします。http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx .

void button1_Click(object sender, EventArgs e)
{
   var worker = new BackgroundWorker();
   worker.DoWork += (s,e) =>
   {
       // Do some work.
   };
   worker.RunWorkerCompleted += (s,e) =>
   {
       // Update the UI.
   }
   worker.RunWorkerAsync();
}
于 2012-10-25T05:57:48.333 に答える