长时间运行的进程冻结UI,如何使用线程更新?

Ari*_*ian 1 c# multithreading winforms

我已为长时间运行的进程编写了此示例代码,但Windows窗体冻结直到该过程完成.如何更改代码以使工作并行运行?

var ui = TaskScheduler.FromCurrentSynchronizationContext();
Task t = Task.Factory.StartNew(delegate
{
    textBox1.Text = "Enter Thread";
    for (int i = 0; i < 20; i++)
    {
        //My Long Running Work
    }
    textBox1.Text = textBox1.Text + Environment.NewLine + "After Loop";
}, CancellationToken.None, TaskCreationOptions.None, ui);
Run Code Online (Sandbox Code Playgroud)

Oha*_*der 7

你可以使用延续.我不记得确切的语法,但它是这样的:

textBox1.Text = "Enter Thread"; //assuming here we're on the UI thread
Task t = Task.Factory.StartNew(delegate
{                
    for (int i = 0; i < 20; i++)
    {
        //My Long Running Work
    }
    return result;
})
.ContinueWith(ret => textBox1.Text = textBox1.Text + Environment.NewLine + result, 
    TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)

另一种选择是:

Task t = Task.Factory.StartNew(delegate
{
    YourForm.Invoke((Action)(() => textBox1.Text = "Enter Thread");
    for (int i = 0; i < 20; i++)
    {
        //My Long Running Work
    }
    YourForm.Invoke((Action)(() => textBox1.Text = textBox1.Text + Environment.NewLine + result);}, 
        CancellationToken.None, TaskCreationOptions.None);
Run Code Online (Sandbox Code Playgroud)

同样,我不记得确切的语法,但想法是你想在不同于UI线程的线程上执行长操作,但是在UI线程上报告进度(包括完成).

顺便说一句,BackGroundWorker类在这里也能很好地工作(我个人非常喜欢它).