2011-10-25 17 views
5

C#でWindowsフォームアプリケーションを作成しているので、1回のボタンクリックで長時間実行される手順が多く実行されます。これにより、GUIが実行されるまでフリーズします。また、実行中に、私はリストボックスに情報&のステータスを記録しています。ただし、実行が完了するまで、ステータスはリストボックスで更新されません。実行と並行してステータスがリストボックスで更新され、GUIがフリーズしないように、コードをどのように記述するべきですか。Windowsフォームでの非同期実行

スレッドを初めて使う人です。これがどのように行われたかの例を挙げてください。

ご協力いただきありがとうございます。

答えて

12

これらのシナリオを処理する最も簡単で効率的な方法は、BackgroundWorkerを使用することです。

DoWorkイベントハンドラに重いコードを置き、ProgressChangedイベントハンドラを通してGUIを更新します。

あなたはチュートリアルhere
またはより良いを見つけることができ、彼らはあなたがそれを読んだ後、より具体的な質問がある場合msdn
で、私は幸せになるだろう「する方法」義務付けるために作られました。

+0

ありがとうございます。解決策は非常に役に立ちます – RSP

4

ヒヒは、必要に応じて背景やUIスレッド上のコードの実行を簡素化し、あなたがネット4を使用しているか、上記Taskクラス

Taskクラスを使用することができれば行くための一つの方法は、別の方法でバックグラウンドワーカーアプローチで言ったように。あなたは

リードCopsey、Jr.のはネット上の並列処理に非常に良いseriesを持っているタスクContinuationを使用して設定したイベントとコールバックの余分なコードを書く避けるTaskクラスをすることができます使用すると、例えば、aのそれ

を見てみましょう同期的なやり方は可能です

//bad way to send emails to all people in list, that will freeze your UI 
foreach (String to in toList) 
{ 
    bool hasSent = SendMail(from, "password", to, SubjectTextBox.Text, BodyTextBox.Text); 
    if (hasSent) 
    { 
     OutPutTextBox.appendText("Sent to: " + to); 
    } 
    else 
    { 
     OutPutTextBox.appendText("Failed to: " + to); 
    } 
} 

//good way using Task class which won't freeze your UI 
string subject = SubjectTextBox.Text; 
string body = BodyTextBox.Text; 
var ui = TaskScheduler.FromCurrentSynchronizationContext(); 
List<Task> mails = new List<Task>(); 
foreach (string to in toList) 
{ 
    string target = to; 
    var t = Task.Factory.StartNew(() => SendMail(from, "password", target, subject, body)) 
    .ContinueWith(task => 
    { 
     if (task.Result) 
     { 
      OutPutTextBox.appendText("Sent to: " + to); 
     } 
     else 
     { 
      OutPutTextBox.appendText("Failed to: " + to); 
     } 
    }, ui); 
} 
+0

パラレルライブラリが常に新しいスレッドを作成するわけではないので注意してください。たとえば、Parallel.Foreachは異なるループごとにスレッドを作成しません。 –

関連する問題