2011-12-17 79 views
2

我面临一个问题。我点击了一个正在调用几个方法的按钮,虽然主线程已经锁定,所以我创建了我的类的一个实例(即Form1),例如Form1Object然后按钮调用方法如下:Form1Object.Check1等等。主线程锁定在C#

尽管线程仍然锁定(即GUI在一段时间内变得没有响应)有没有办法解决这个问题,任何示例都将不胜感激。

有问题的代码如下:

private void StartChecks_Click(object sender, EventArgs e) 
{ 
    Form1 Form1Object = new Form1(); 
    Form1Object.InitChecks(); 
} 

public void InitChecks() 
{ 
    Check1(); 
    Check2(); 
    Check3(); 
    Check4(); 
    Check5(); 
    Check6(); 
    Check7(); 
}  
+1

你应该看看使用BackgroundWorker,但在这种情况下,它甚至可能足以使用Application.DoEvents();. http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx – eandersson

+0

您可以通过在单独的线程上运行代码来解决此问题。这就是你保持主要(UI)线程不被锁定的原因。事实上,你不应该在UI线程上精确运行长时间运行的操作,因为它会导致UI无响应。这里的解决方案似乎很明显... –

+1

另外,**从不使用Application.DoEvents()**。无法强调这一点。学习如何正确地执行多线程(或至少使用'BackgroundWorker')。不要破解它。忽略所有以不同方式告诉你的人。 –

回答

2

你需要做的是开始一个并行线程做检查什么,这样你就不会锁定了主线程:

private void StartChecks_Click(object sender, EventArgs e) 
    { 
     Form1 Form1Object = new Form1(); 
     Thread t = new Thread(
      o => 
      { 
       Form1Object.InitChecks(); 
      }); 
     t.Start(); 
    } 

希望你不需要从这些计算中实际检索任何东西,所以你可以开火并忘掉它。

+1

干杯,小写字母,“开始”需要大写。非常感谢! –

4

创建新窗体不会启动新线程。您将不得不将这些CheckN()方法移动到BackgroundWorker

private void StartChecks_Click(object sender, EventArgs e) 
{ 
    Form1 Form1Object = new Form1(); 
    var worker = new BackgroundWorker(); 
    worker.DoWork += (s, arg) => 
    { 
    Form1Object.InitChecks(); 
    }; 

    // add progress, completed events 

    worker.RunWorkerAsync(); 
} 

但请注意,这需要检查是独立的,不要与任何控件交互。

+0

干杯,2个错别字BackgroundWorker和你缺少一个分号(底部第二行) –

0

您有几种选择这里,并使用它们取决于你的技能/首选项/要求:

  • 如果你没有,而你处理表单上的任何更新,启动另一个线程,并呼吁一切线程,和更新UI在适当的时候(当一切都完了)
  • 如果你需要同时处理,你有几种选择到您的表单上更新的东西:
    • 要么使用Application.DoEvents()从每次使用
    • 方法的处理循环
    • 然后开始一个新的线程与Invoke()更新表单控件 - 如果你尝试直接更新它们,你就会有麻烦

如果你愿意发表意见和决定的选项之一,我可以提供更多的信息,只是...