c#交叉螺纹错误

c#交叉螺纹错误,c#,multithreading,exception,C#,Multithreading,Exception,我写了一个程序,保存了传感器的3个不同位置。如果传感器回到保存位置,我希望文本框的背景颜色为绿色。由于数值变化非常快且精确,我决定只比较前3个数值。因此,我启动了我的程序,并通过单击保存了一个位置。该位置已保存,文本框立即变为绿色,这很好,因为传感器仍处于该位置。但在那之后,我得到了一个交叉线程的例外,我不明白它。我是C#新手,我想我在函数开始时通过调用解决了这个问题 private void Safe_Position1(TextBox tBr1, TextBox tBi1,

我写了一个程序,保存了传感器的3个不同位置。如果传感器回到保存位置,我希望文本框的背景颜色为绿色。由于数值变化非常快且精确,我决定只比较前3个数值。因此,我启动了我的程序,并通过单击保存了一个位置。该位置已保存,文本框立即变为绿色,这很好,因为传感器仍处于该位置。但在那之后,我得到了一个交叉线程的例外,我不明白它。我是C#新手,我想我在函数开始时通过调用解决了这个问题

        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")
        {

        }
    }
}