2011-10-25 103 views
5

我書面方式一個Windows窗體在一個單一的按一下按鈕,執行了大量的長期運行的程序,C#應用程序。這會使GUI凍結直到執行。另外,在執行過程中,我記錄的信息&狀態到列表框。但是,直到執行完成,狀態不會在列表框中得到更新。我應該如何進行編碼,以便狀態在執行的同時在列表框中得到更新,並且GUI不會凍結。異步執行形成

我新的線程。你能舉一些例子說明這是如何完成的嗎?

在此先感謝您的幫助。

回答

12

最簡單而有效的方式來處理這些場景中,是使用BackgroundWorker

你把你的重碼在DoWork的事件處理程序,並更新通過ProgressChanged事件處理程序的GUI。

你可以找到一個教程here
甚至更​​好,他們做了一個「如何」在msdn
如果你看完後更具體的問題,我會很樂意效勞。

+0

非常感謝。該解決方案是非常有幫助的 – RSP

4

狒狒說要去一個辦法是後臺工作方法的另一種方式,如果你使用的是.NET 4級以上可以使用Task

Task類簡化了對背景和UI線程代碼的執行需要。使用任務類,你能避免使用任務Continuation

裏德•科普塞,小有並行.Net的一個非常好的series書寫設置事件和回調的額外的代碼也看看它

例如同步服務方式可以是

//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不會爲每個不同的循環創建一個線程。 –