Я пытался отложить добавлять средства управления к своей основной форме, с целью убыстриться это - время начала. Хорошо я работаю в следующем исключении:
Операция перекрестного потока, не допустимая: Управляйте '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, так как это - вызов рекурсии.
Так, если бы кто-либо встретил подобную проблему, то Вы могли бы сказать мне, что я делал неправильно?
Проблема в вашем коде заключается в том, что вы добавляете две кнопки.
Поместите код после блока 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);
}
}
Использовать поток для простого добавления кнопки - очень дорого! Вместо этого используйте ThreadPool.
Используйте вместо этого анонимные методы. Объяснение ниже.
Если у нас есть такая форма:
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";
}