如何在长时间运行的功能中更新UI(文本字段)?

ech*_*ion 3 c# .net-4.0 winforms

我知道这个问题可能没有意义,而且我正在努力想办法解释它,所以我将展示一段代码来帮助.我在visual studio express 2010上使用Winforms:

private void button1(object sender, EventArgs e)
    {
        txtOutput.Text += "Auto-collecting variables. This may take several minutes";
        string v = foo();
        txtOutput.Text += "\n" + v;
        string b = bar();
        txtOutput.Text += "\n" + b;

        txtOutput.SelectionStart = txtOutput.Text.Length;
        txtOutput.ScrollToCaret(); //scrolls to the bottom of textbox
    }
Run Code Online (Sandbox Code Playgroud)

所以基本上,当用户点击button1时,我希望"自动收集变量..."显示在文本框中,然后让foo()执行,显示它,然后执行bar(),然后显示.

当前正在发生的是foo()和bar()执行,然后在执行foo()和bar()之后一切都显示(需要几分钟的函数).无论如何要解决这个问题,还是有解决方法?

编辑:C#的版本是4.0.如果我更新到4.5或5.0,没有.NET 4.5/5.0的计算机能够运行.exe吗?

Ser*_*rvy 6

C#5.0让这件事变得微不足道.

在后台线程中执行长时间运行的任务,Task.Run并使用它await来执行方法的其余部分作为UI线程中的延续,而不会在异步任务的持续时间内阻塞UI线程.

private async void button1(object sender, EventArgs e)
{
    txtOutput.Text += "Auto-collecting variables. This may take several minutes";
    string v = await Task.Run(() => foo());
    txtOutput.Text += "\n" + v;
    string b = await Task.Run(() => bar());
    txtOutput.Text += "\n" + b;

    txtOutput.SelectionStart = txtOutput.Text.Length;
    txtOutput.ScrollToCaret(); //scrolls to the bottom of textbox
}
Run Code Online (Sandbox Code Playgroud)

您可以在C#4.0中执行相同的操作:(第一个解决方案将由编译器转换为类似的东西.)

private  void button1(object sender, EventArgs e)
{
    txtOutput.Text += "Auto-collecting variables. This may take several minutes";
    Task.Factory.StartNew(() => foo())
        .ContinueWith(t => txtOutput.Text += "\n" + t.Result
            , TaskScheduler.FromCurrentSynchronizationContext())
        .ContinueWith(t => bar())
        .ContinueWith(t =>
        {
            txtOutput.Text += "\n" + t.Result;
            txtOutput.SelectionStart = txtOutput.Text.Length;
            txtOutput.ScrollToCaret(); //scrolls to the bottom of textbox
        }
            , TaskScheduler.FromCurrentSynchronizationContext());
}
Run Code Online (Sandbox Code Playgroud)