SilverSilencer
SilverSilencer

Reputation: 93

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

I have some project where in one case when some form opens it just freezes (not responding) and closes after short while. I am working on this problem for 2 days and can't find solution. So now I decided to make new project (simple) and only test this opening forms and I found out that it only happens while I call function to open form from some loop or timer.

Here is link to zip file of this simple small project

In sample project I made simple app who opens new form every 5 seconds and all those forms are not responsive, while if ou click button which uses same function it's opened normally.

If anyone can just explain how to fix this (I need to keep the loop) so that those forms will not freeze anymore it would be great, I am totally lost...

Here is the code if anyone will see the problem just from code:

FORM 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();
        }
    }
}

FORM 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...";
        }
    }
}

PROGRAM:

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")));
        }

    }
}

Upvotes: 0

Views: 920

Answers (1)

It is a common thread issue. You are trying to access something that doesn't belong to your thread. Use BeginInvoke:

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

}

Upvotes: 1

Related Questions