windows窗体中的异步执行

本文关键字:异步 执行 窗体 windows | 更新日期: 2023-09-27 18:12:14

我正在用c#编写一个Windows窗体应用程序,它可以在单击一个按钮时执行许多长时间运行的过程。这使得GUI冻结直到执行。此外,在执行过程中,我正在记录信息&状态到列表框。但是,在执行完成之前,状态不会在列表框中更新。我应该如何编写代码,使状态在列表框中与执行并行更新,使GUI不会冻结。

我是新手。你能举例说明一下这是怎么做到的吗?

提前感谢您的帮助。

windows窗体中的异步执行

处理这些情况的最简单而有效的方法是使用BackgroundWorker

你把繁重的代码放在DoWork事件处理程序中,并通过ProgressChanged事件处理程序更新你的GUI。

你可以在这里找到一个教程
或者更好的是,他们在msdn
上做了一个"如何做"如果您在阅读后有更具体的问题,我很乐意为您解答。

正如Baboon所说,一种方法是使用后台工作器方法另一种方法是如果你使用。net 4或更高版本,可以使用任务类

Task类根据需要简化了后台和UI线程上的代码执行。使用Task类,可以通过使用Task Continuation 来避免编写设置事件和回调的额外代码。

Reed Copsey, Jr.有一个非常好的关于。net并行的系列文章,也可以看一看

例如,同步方式可以是
//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);
 }