Add a control on a form, from another Thread

12,830

The problem in your code is that your are adding two buttons.

Put the code after the if block in an else block.

private void AddButton() { 
        if(this.InvokeRequired){
            this.Invoke(new MethodInvoker(this.AddButton));
        }
        else {
           Random random = new Random(2);
           Thread.Sleep(20);
           Button button = new Button();
           button.Size = new Size(50,50);
           button.Location = new Point(random.Next(this.Width),random.Next(this.Height));
           this.Controls.Add(button);
        }
    }
Share:
12,830
Gico
Author by

Gico

Updated on July 21, 2022

Comments

  • Gico
    Gico almost 2 years

    I was trying to postpone adding controls to my main form, with a goal to speed up it's start time. Well I run in the following exception:

    Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.

    I tried to simply the problem on a smaller example but the problem stays. Here is my code:

    using System;
    using System.Drawing;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace AddConrolFromAnotherThread {
        public partial class Form1 : Form {
    
            public Form1() {
                InitializeComponent();
            }
    
    
            private void AddButton() { 
                if(this.InvokeRequired){
                    this.Invoke(new MethodInvoker(this.AddButton));
                }
                Random random = new Random(2);
                Thread.Sleep(20);
                Button button = new Button();
                button.Size = new Size(50,50);
                button.Location = 
                    new Point(random.Next(this.Width),random.Next(this.Height));
                    this.Controls.Add(button);
            }
    
            private void buttonStart_Click(object sender, EventArgs e) {
                Thread addControlThread = 
                    new Thread(new ThreadStart(this.AddButton));
                addControlThread.Start();
            }
        }
    }
    

    I did use the Invoke method and did check if InvokeRequiered is true, but InvokeRequiered keep staying "true". I really don't understand that. At least I would expect StackOverflow exception, since this is a recursion call.

    So, if anyone met the similar problem, please could you tell me what did I do wrong?