C# 使用C将变量从线程传递到另一个窗体#

C# 使用C将变量从线程传递到另一个窗体#,c#,winforms,multithreading,C#,Winforms,Multithreading,我试图将两个变量从一个线程(MainForm)传递到另一个表单,但这样做时会发生错误 private void TrackingThread( ) { float targetX = 0; float targetY = 0; while ( true ) { camera1Acquired.WaitOne( ); camera2Acquired.WaitOne( );

我试图将两个变量从一个线程(MainForm)传递到另一个表单,但这样做时会发生错误

private void TrackingThread( )
    {
        float targetX = 0;
        float targetY = 0;

        while ( true )
        {
            camera1Acquired.WaitOne( );
            camera2Acquired.WaitOne( );

            lock ( this )
            {
                // stop the thread if it was signaled
                if ( ( x1 == -1 ) && ( y1 == -1 ) && ( x2 == -1 ) && ( y2 == -1 ) )
                {
                    break;
                }

                // get middle point
                targetX = ( x1 + x2 ) / 2;
                targetY = ( y1 + y2 ) / 2;
            }

            if (directionForm != null)
            {
                directionForm.RunMotors(targetX, targetY);
            }
        }
    }
在directionForm表单中,我只是简单地显示变量targetX和targetY。 directionForm.RunMotors()的代码如下:

public void RunMotors(float x, float y)
    {
        label1.Text = "X-ordinate " + x.ToString();
        label2.Text = "Y-ordinate " + y.ToString();
    }
尝试显示两个变量时出错: “未处理InvalidOperationException 交叉线程操作无效:控制标签1是从创建它的线程“”以外的线程访问的

我该怎么办

提前感谢

整个GUI不是线程安全的,您看到的错误是故意检查的。您必须将该方法传递给messagepump,以便在主线程上执行它。使用类似于:

if (directionForm != null)            
{
   var a = new Action<float, float>(RunMotors);
   directionForm.Invoke(a, targetX, targetY);
}
if(directionForm!=null)
{
var a=新动作(运行电机);
调用(a,targetX,targetY);
}

您必须从UI线程升级UI。在UI线程中调用方法。 这基本上和亨克·霍特曼写的一样。 UpdateUIDelegate必须具有与RunMotors方法相同的签名

void UpdateUI() {
    if (this.yourControl.InvokeRequired) {
        object[] ob = new object[] { targetX, targetY };
        UpdateUIDelegate updDel = new UpdateUIDelegate(RunMotors);
        this.yourControl.Invoke(updDel, ob);
    }
    else {
        this.RunMotors(targetX, targetY);
    }
}

void RunMotors(targetX, targetY)
{
    // action
}

还要检查属性

当控件的创建线程以外的线程尝试访问该控件的某个方法或属性时,通常会导致不可预知的结果。常见的无效线程活动是对访问控件句柄属性的错误线程的调用。将CheckForIllegalCrossThreadCalls设置为true,以便在调试时更轻松地查找和诊断此线程活动。请注意,当应用程序在调试器外部启动时,非法的跨线程调用总是会引发异常


由于调用总是来自另一个线程,您最好跳过
if(invokererequired)
逻辑。@kirstom:如果您的问题得到了回答,请标记。