打开新表单会导致它在执行循环/计时器时冻结(不响应)

Opening new form causes it to freeze (not responding) while doing loop / timer

我有一些项目,在一种情况下,当某些表单打开时它只是冻结(没有响应)并在短时间内关闭。我正在处理这个问题 2 天,但找不到解决方案。所以现在我决定制作新项目(简单)并且只测试这个打开表单,我发现它只发生在我从某个循环或计时器调用函数打开表单时。

Here is link to zip file of this simple small project

在示例项目中,我制作了一个简单的应用程序,每 5 秒打开一个新表单,所有这些表单都没有响应,而如果您单击使用相同功能的按钮,它会正常打开。

如果有人能解释一下如何解决这个问题(我需要保持循环),这样这些表格就不会再冻结,那就太好了,我完全迷路了...

如果有人仅从代码中看到问题,这里是代码:

表格 1

using System;
using System.Threading;
using System.Windows.Forms;

namespace TestForm
{
    public partial class Form1 : Form
    {
        bool flag = true;
        private Thread worker;

        public Form1()
        {
            InitializeComponent();
            this.worker = new Thread(new ThreadStart(this.PerformMacro));
            this.worker.IsBackground = true;
            this.worker.Start();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Program.newForm2Window();
        }

        private void PerformMacro()
        {
            while (flag)
            {
                Thread.Sleep(5000);
                Program.openform2();
                //flag = false;
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            Program.openform2();
        }
    }
}

表格 2

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestForm
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            this.Text = "Form2 - " + Program.form2List.Count;
        }

        public delegate void Action();

        public void MakeNMac(string text)
        {
            label1.Text = "Label changed...";
        }
    }
}

计划:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestForm
{
    static class Program
    {
        public static List<Form2> form2List = new List<Form2>();

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());            
        }

        public static Form2 newForm2Window()
        {
            Form2 item = new Form2();
            form2List.Add(item);
            item.Show();
            return item;
        }

        public static void openform2()
        {
            newForm2Window();
            Form2 miew = Program.form2List[Program.form2List.Count - 1];
            miew.BeginInvoke((Form2.Action)(() => miew.MakeNMac("test")));
        }

    }
}

这是一个常见的线程问题。您正在尝试访问不属于您的线程的内容。使用 BeginInvoke:

private void PerformMacro()
{
    //Dont forget to exit the loop somehow!
    while (flag)
    {
        Thread.Sleep(5000);
        BeginInvoke( new MethodInvoker( Program.openform2 ) );
        //flag = false;
    }

}