代码之家  ›  专栏  ›  技术社区  ›  Gico

从另一个线程在窗体上添加控件

  •  6
  • Gico  · 技术社区  · 16 年前

    我试图推迟在主窗体中添加控件,以加快开始时间。我遇到了以下例外情况:

    跨线程操作无效: 从线程访问的控件“Form1” 除了创建的线程 在。

    我试图简单地用一个小例子来说明这个问题,但问题仍然存在。这是我的代码:

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

    我确实使用了invoke方法,并检查invokeRequiried是否为true,但invokeRequiried保持“true”。我真的不明白。至少我会期望stackoverflow异常,因为这是一个递归调用。

    所以,如果有人遇到类似的问题,你能告诉我我做错了什么吗?

    4 回复  |  直到 7 年前
        1
  •  5
  •   Jehof    16 年前

    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);
            }
        }
    
        2
  •  1
  •   Stephen Rauch Afsar Ali    7 年前

    private void AddButton() { 
        if(this.InvokeRequired) {
            Invoke((MethodInvoker)delegate ()
            {
                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);
         });
    }
    
        3
  •  0
  •   sashaeve    16 年前

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(Start));
            t.Start();
        }
    
        private void UpdateText()
        {
            button1.Text = "New Text";
        }
    
        void Start()
        {
            UpdateText();
        }
    }
    

    private delegate void MyDelegate();
    
    private void UpdateText()
    {
        if (button1.InvokeRequired)
        {
           button1.Invoke(new MyDelegate(UpdateText));
        }
        button1.Text = "New Text";
    }
    

    void Start() 
    {
        this.Invoke((MyDelegate)delegate
        {
            UpdateText();
        });
    }
    
    private void UpdateText()
    {
        button1.Text = "New Text";
    }
    
        4
  •  0
  •   Islam Yahiatene    16 年前