Я сделал похожую (не ту же ситуацию - вы должны понимать, не копировать, вставить) ситуацию для вас.
при нажатии кнопки я создаю 3 потока, которые обновляют текст в текстовых полях (которые были созданы в потоке пользовательского интерфейса))
private void btnStart_Click(object sender, EventArgs e)
{
Thread t1 = new Thread(() => ThreadRunner(1));
Thread t2 = new Thread(() => ThreadRunner(2));
Thread t3 = new Thread(() => ThreadRunner(3));
t1.Start();
t2.Start();
t3.Start();
}
private void ThreadRunner(int threadNum)
{
while(true)
{
TextBoxUpdater(threadNum);
Thread.Sleep(100 * threadNum);
}
}
и метод, который вызывается для обновления текстовых полей,
private void TextBoxUpdater(int num)
{
//here i m checking, if it is from different thread then UI thread
//if yes then Invoke is used,
// so it will call the same method but in UI thread
if(this.InvokeRequired)
{
txtBox1.BeginInvoke(new Action(() => TextBoxUpdater(num)));
txtBox2.BeginInvoke(new Action(() => TextBoxUpdater(num)));
txtBox3.BeginInvoke(new Action(() => TextBoxUpdater(num)));
}
else
{
//If it is UI thread (meaning this call is coming from If part of this method)
//and as it is UI thread now, we can update textbox's text
txtBox1.Text = num.ToString();
txtBox2.Text = num.ToString();
txtBox3.Text = num.ToString();
}
//but after all above checks, we are leving below code without any checking
//so once if part of this code will call this function again and else part of code runs
// and then after completing that call,
// flow will retun back to if part (not that it is not UI thread),
// then flow will directly checks below codition and throw an exception
if (txtBox1.Text.Substring(1) == "1")
{
}
}
с минимальными изменениями, которые вы можете сделать, как показано ниже, чтобы предотвратить исключение.
private void TextBoxUpdater(int num)
{
//here i m checking, if it is from different thread then UI thread
//if yes then Invoke is used,
// so it will call the same method but in UI thread
if(this.InvokeRequired)
{
txtBox1.BeginInvoke(new Action(() => TextBoxUpdater(num)));
txtBox2.BeginInvoke(new Action(() => TextBoxUpdater(num)));
txtBox3.BeginInvoke(new Action(() => TextBoxUpdater(num)));
}
else
{
//If it is UI thread (meaning this call is coming from If part of this method)
//and as it is UI thread now, we can update textbox's text
txtBox1.Text = num.ToString();
txtBox2.Text = num.ToString();
txtBox3.Text = num.ToString();
//perform this logic too insdie of else block
if (txtBox1.Text.Substring(1) == "1")
{
}
}
}
Но тогда и ваш метод вызовет слишком много ненужных вызовов TextBoxUpdater
. Вы должны задаться вопросом, почему я это заявляю.
поэтому, чтобы исправить эту часть, вы должны изменить свой метод, как показано ниже.
private void TextBoxUpdater(int num)
{
if (this.InvokeRequired)
{
//if current call is form other than UI thread invoke to UI thread
this.BeginInvoke(new Action(() => TextBoxUpdater(num)));
}
else
{
//If it is UI thread (meaning this call is coming from If part of this method)
//and as it is UI thread now, we can update textbox's text
txtBox1.Text = num.ToString();
txtBox2.Text = num.ToString();
txtBox3.Text = num.ToString();
if (txtBox1.Text.Substring(1) == "1")
{
}
}
}