2012-10-25 58 views
2

下面这个简单的代码使UI线程挂起。如何避免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线程冻结。

什么是最好的解决方案,使其工作?

在此先感谢。

+0

你为什么把'而(真);''中的方法Invoke',你没有任何代码改变用户界面,它会阻止UI线程, –

+0

我希望把一些代码改变UI中循环。我只是在循环中忽略了这些代码,使其看起来很简单。谢谢。 –

回答

2

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

while(true)Invoke方法,所以whenver要更改UI,把代码改变UI的块中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"; 
     })); 
    } 
} 
+0

谢谢。这会帮助我很多。有什么办法可以接受这两个答案吗? –

+0

@YayCplusplus:没办法,你只接受一个答案 –

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线程执行该操作。

此外,您没有异常捕获或进度报告逻辑。我建议看看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(); 
} 
+0

我很欣赏它。非常感谢。 –