C# 使用C将变量从线程传递到另一个窗体#
我试图将两个变量从一个线程(MainForm)传递到另一个表单,但这样做时会发生错误C# 使用C将变量从线程传递到另一个窗体#,c#,winforms,multithreading,C#,Winforms,Multithreading,我试图将两个变量从一个线程(MainForm)传递到另一个表单,但这样做时会发生错误 private void TrackingThread( ) { float targetX = 0; float targetY = 0; while ( true ) { camera1Acquired.WaitOne( ); camera2Acquired.WaitOne( );
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:如果您的问题得到了回答,请标记。