C# 主线程在C中锁定#

C# 主线程在C中锁定#,c#,.net,multithreading,C#,.net,Multithreading,我面临一个问题。我正在单击一个调用多个方法的按钮,尽管主线程正在锁定,所以我创建了我的类的一个实例(即Form1),例如Form1Object,然后该按钮调用了这些方法:Form1Object.Check1等等 尽管线程仍然被锁定(即GUI在一段时间内没有响应),但无论如何都有办法解决这个问题,任何示例都将不胜感激 有关守则如下: private void StartChecks_Click(object sender, EventArgs e) { Form1 Form1Object

我面临一个问题。我正在单击一个调用多个方法的按钮,尽管主线程正在锁定,所以我创建了我的类的一个实例(即
Form1
),例如
Form1Object
,然后该按钮调用了这些方法:
Form1Object.Check1
等等

尽管线程仍然被锁定(即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();
}      

您需要做的是启动一个并行线程来执行检查,这样就不会锁定主线程:

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

希望您不需要从这些计算中实际检索任何内容,因此您可以直接启动并忘记它。

创建新表单不会启动新线程

您必须将这些CheckN()方法移动到一个新的位置


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

您在这里有几个选项,并根据您的技能/偏好/要求使用它们:

  • 如果在处理过程中没有更新表单上的任何内容,请启动另一个线程并调用该线程上的所有内容,并在适当时更新UI(当所有内容完成时)
  • 如果在处理过程中需要更新表单上的内容,您有几个选项:
    • 使用您使用的每个方法的处理循环中的
      Application.DoEvents()
    • 启动一个新线程,然后使用
      Invoke()
      更新表单控件-如果您试图直接更新它们,您将遇到麻烦

如果您愿意对其中一个选项进行评论和决定,我可以提供更多信息……您可能应该考虑使用BackgroundWorker,但在这种情况下,仅使用Application.DoEvents();。您可以通过在单独的线程上运行代码来修复此问题。这就是防止主(UI)线程锁定的方法。事实上,您永远不应该在UI线程上运行长时间运行的操作,因为这会导致UI变得无响应。从这个问题来看,这里的解决方案似乎是显而易见的……而且,永远不要使用
Application.DoEvents()
。这一点怎么强调都不过分。了解如何正确执行多线程(或至少使用
BackgroundWorker
)。别胡闹了。忽略所有告诉你不同意见的人。@CodeInChaos,这只是一个打字错误,我在5秒钟后更新了它。@Fuji:那为什么要把它作为评论发布呢?并建议“在这种情况下,仅仅使用它就足够了”?当然够了。问题是它经常太多了。大多数人不检查链接或阅读文档;这就是为什么他们首先要问这个问题。干杯,小字体,“开始”需要大写。非常感谢!干杯,2个打字错误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();
}