如何避免使用Invoke挂起UI?

时间:2012-10-25 05:36:20

标签: c# multithreading invoke

以下代码使UI线程挂起。

    private void button1_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(Func);
        t.Start();
    }

    private void Func()
    {
        this.Invoke((Action)(() =>
        {
            while (true);
        }));
    }

我想在不同的工作线程中调用Func(),每次单击按钮时都不会冻结任何UI线程。

最好的解决方法是什么?

2 个答案:

答案 0 :(得分:3)

使用您的代码,while(true)正在UI线程上运行,这就是阻止您的UI的原因。

while(true)排除在Invoke方法之外,因此当您想要更改用户界面时,请将代码块更改为Invoke内的用户界面:

private void button1_Click(object sender, EventArgs e)
{
    Thread t = new Thread(Func);
    t.Start();
}

private void Func()
{
    while(true)
    {
       this.Invoke((Action)(() =>
        {
            textBox.Text = "abc";
        }));
    } 
}

答案 1 :(得分:2)

Func()代码确实在非UI线程上运行。但是,this.Invoke然后在UI线程上执行Action!。

尝试这样的事情:

void Func()
{
     // Do some work.

     // Update the UI (must be on UI thread)
     this.Invoke(Action) (() =>
     {
        // Update the UI.
     }));
 }

我可能最好使用BeginInvoke方法。这样非UI线程就不会等待UI线程执行Action。

此外,您没有异常捕获或进度报告逻辑。我建议查看BackgroundWorker课程; http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

void button1_Click(object sender, EventArgs e)
{
   var worker = new BackgroundWorker();
   worker.DoWork += (s,e) =>
   {
       // Do some work.
   };
   worker.RunWorkerCompleted += (s,e) =>
   {
       // Update the UI.
   }
   worker.RunWorkerAsync();
}