c#交叉螺纹错误
我写了一个程序,保存了传感器的3个不同位置。如果传感器回到保存位置,我希望文本框的背景颜色为绿色。由于数值变化非常快且精确,我决定只比较前3个数值。因此,我启动了我的程序,并通过单击保存了一个位置。该位置已保存,文本框立即变为绿色,这很好,因为传感器仍处于该位置。但在那之后,我得到了一个交叉线程的例外,我不明白它。我是C#新手,我想我在函数开始时通过调用解决了这个问题c#交叉螺纹错误,c#,multithreading,exception,C#,Multithreading,Exception,我写了一个程序,保存了传感器的3个不同位置。如果传感器回到保存位置,我希望文本框的背景颜色为绿色。由于数值变化非常快且精确,我决定只比较前3个数值。因此,我启动了我的程序,并通过单击保存了一个位置。该位置已保存,文本框立即变为绿色,这很好,因为传感器仍处于该位置。但在那之后,我得到了一个交叉线程的例外,我不明白它。我是C#新手,我想我在函数开始时通过调用解决了这个问题 private void Safe_Position1(TextBox tBr1, TextBox tBi1,
private void Safe_Position1(TextBox tBr1, TextBox tBi1, TextBox tBj1, TextBox tBk1, string[] text)
{
if (button3clicked == true)
{
if (!Dispatcher.CheckAccess())
{
textBox5.Dispatcher.BeginInvoke(new Action(() => Safe_Position1(tBr1, tBi1, tBj1, tBk1, text)));
}
if (!Dispatcher.CheckAccess())
{
textBox7.Dispatcher.BeginInvoke(new Action(() => Safe_Position1(tBr1, tBi1, tBj1, tBk1, text)));
}
if (!Dispatcher.CheckAccess())
{
textBox8.Dispatcher.BeginInvoke(new Action(() => Safe_Position1(tBr1, tBi1, tBj1, tBk1, text)));
}
if (!Dispatcher.CheckAccess())
{
textBox9.Dispatcher.BeginInvoke(new Action(() => Safe_Position1(tBr1, tBi1, tBj1, tBk1, text)));
}
else
{
tBr1.Text = text[0];
tBi1.Text = text[1];
tBj1.Text = text[2];
tBk1.Text = text[3];
button3clicked = false;
}
string firstthreetBr1 = new string(text[0].Take(3).ToArray());
string firstthreetBi1 = new string(text[1].Take(3).ToArray());
string firstthreetBj1 = new string(text[2].Take(3).ToArray());
string firstthreetBk1 = new string(text[3].Take(3).ToArray());
if (firstthreetBr1 == tBr1.Text.Substring(0,3)) <------ EXCEPTION HERE
{
tBr1.Background = Brushes.Green;
}
if (firstthreetBi1 == tBi1.Text.Substring(0, 3))
{
tBi1.Background = Brushes.Green;
}
if (firstthreetBj1 == tBj1.Text.Substring(0, 3))
{
tBj1.Background = Brushes.Green;
}
if (firstthreetBk1 == tBk1.Text.Substring(0, 3))
{
tBk1.Background = Brushes.Green;
}
}
}
private void Safe_Position1(文本框tBr1、文本框tBi1、文本框tBj1、文本框tBk1、字符串[]文本)
{
如果(按钮3单击==真)
{
如果(!Dispatcher.CheckAccess())
{
textBox5.Dispatcher.BeginInvoke(新操作(()=>安全位置1(tBr1、tBi1、tBj1、tBk1、text));
}
如果(!Dispatcher.CheckAccess())
{
textBox7.Dispatcher.BeginInvoke(新操作(()=>安全位置1(tBr1、tBi1、tBj1、tBk1、text));
}
如果(!Dispatcher.CheckAccess())
{
textBox8.Dispatcher.BeginInvoke(新操作(()=>安全位置1(tBr1、tBi1、tBj1、tBk1、text));
}
如果(!Dispatcher.CheckAccess())
{
textBox9.Dispatcher.BeginInvoke(新操作(()=>安全位置1(tBr1、tBi1、tBj1、tBk1、text));
}
其他的
{
tBr1.Text=文本[0];
tBi1.Text=文本[1];
tBj1.Text=文本[2];
tBk1.Text=文本[3];
按钮3clicked=假;
}
string firstthreetBr1=新字符串(文本[0]。获取(3.ToArray());
string firstthreetBi1=新字符串(文本[1]。获取(3).ToArray();
string firstthreetBj1=新字符串(文本[2]。获取(3.ToArray());
string firstthreetBk1=新字符串(文本[3]。获取(3.ToArray());
如果(firstthreetBr1==tBr1.Text.Substring(0,3))如Matthew所评论的,您必须在每个BeginInvoke()之后编写return语句。此代码引发异常,因为在您的方法从BeginInvoke()返回后,它会深入到代码中。我做了类似的操作(不一样-您应该理解为不复制粘贴)你的情况
单击按钮时,我正在创建3个线程,它们正在更新文本框的文本(在UI线程中创建)
以及被调用以更新文本框的方法
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")
{
}
}
}
什么异常?在哪一行?Safe vs Save vs Safe每个BeginInvoke()
块都需要一个return
否则调用BeginInvoke()
后,if
s后面的代码仍将异常。异常消息是什么
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")
{
}
}
}