Добавьте управление на форме от другого Потока

Я пытался отложить добавлять средства управления к своей основной форме, с целью убыстриться это - время начала. Хорошо я работаю в следующем исключении:

Операция перекрестного потока, не допустимая: Управляйте '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();
        }
    }
}

Я действительно использовал Вызвать метод и действительно проверял, верен ли InvokeRequiered, но InvokeRequiered продолжают оставаться "верными". Я действительно не понимаю это. По крайней мере, я ожидал бы исключение StackOverflow, так как это - вызов рекурсии.

Так, если бы кто-либо встретил подобную проблему, то Вы могли бы сказать мне, что я делал неправильно?

6
задан Enigmativity 15 October 2018 в 01:13
поделиться

3 ответа

Проблема в вашем коде заключается в том, что вы добавляете две кнопки.

Поместите код после блока if в блок else.

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);
        }
    }
5
ответ дан 17 December 2019 в 02:28
поделиться

Использовать поток для простого добавления кнопки - очень дорого! Вместо этого используйте ThreadPool.

0
ответ дан 17 December 2019 в 02:28
поделиться

Используйте вместо этого анонимные методы. Объяснение ниже.

Если у нас есть такая форма:

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

Это вызовет исключение.

Измените 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";
}
0
ответ дан 17 December 2019 в 02:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: