【问题标题】:Long running process freezing UI, how to update with threading?长时间运行的进程冻结 UI,如何使用线程更新?
【发布时间】:2013-06-12 00:27:14
【问题描述】:

我已经为一个长时间运行的进程编写了这个示例代码,但是 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);

【问题讨论】:

  • 尽量不要使用同步上下文来运行它,这意味着你需要启动一个子任务来更新GUI,或者使用invoke。
  • 如果我删除“ui”参数,它会引发“跨线程”异常

标签: c# multithreading winforms


【解决方案1】:

您可以使用延续。我不记得确切的语法,但它类似于:

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());

另一种选择是:

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);

同样,我不记得确切的语法,但想法是您希望在 不同于 UI 线程的线程上执行长操作,但在界面线程。

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

【讨论】:

  • 好吧,谢谢。我如何将 t 的值返回给更新程序操作?谢谢,谢谢
  • @Nima - 查看我的编辑。我建议你阅读一个简单的教程,例如:codethinked.com/post/2010/01/25/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-23
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2013-09-14
相关资源
最近更新 更多