2011-10-25 60 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不会为每个不同的循环创建一个线程。 –