C# 我如何调用Form1或此?

C# 我如何调用Form1或此?,c#,C#,我有这个功能: public void NudgeMe() { int xCoord = this.Left; int yCoord = this.Top; int rnd = 0; Random RandomClass = new Random(); for (int i = 0; i <= 500; i++) {

我有这个功能:

public void NudgeMe()
        {


            int xCoord = this.Left;
            int yCoord = this.Top;


            int rnd = 0;


            Random RandomClass = new Random();

            for (int i = 0; i <= 500; i++)
            {
                rnd = RandomClass.Next(xCoord + 1, xCoord + 15);
                this.Left = rnd;
                rnd = RandomClass.Next(yCoord + 1, yCoord + 15);
                this.Top = rnd;
            }
            this.Left = xCoord;
            this.Top = yCoord;
        }
我得到的异常是:invalidOperationException 跨线程操作无效:从创建控件“Form1”的线程以外的线程访问控件“Form1”

该异常位于NudgeMe()中的行上:

这条线漆成绿色

System.InvalidOperationException was unhandled by user code
  Message=Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.Control.get_Handle()
       at System.Windows.Forms.Control.SetBoundsCore(Int32 x, Int32 y, Int32 width, Int32 height, BoundsSpecified specified)
       at System.Windows.Forms.Form.SetBoundsCore(Int32 x, Int32 y, Int32 width, Int32 height, BoundsSpecified specified)
       at System.Windows.Forms.Control.SetBounds(Int32 x, Int32 y, Int32 width, Int32 height, BoundsSpecified specified)
       at System.Windows.Forms.Control.set_Left(Int32 value)
       at HardwareMonitoring.Form1.NudgeMe() in D:\C-Sharp\HardwareMonitoring\HardwareMonitoring\Hardwaremonitoring\Form1.cs:line 782
       at HardwareMonitoring.Form1.backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in D:\C-Sharp\HardwareMonitoring\HardwareMonitoring\Hardwaremonitoring\Form1.cs:line 727
       at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
       at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
  InnerException: 

从后台线程更改UI线程是一个很大的禁忌。您可以从后台工作程序中删除直接访问UI的代码,或者看看这个问题


您需要将修改同步到表单的

修改在不同于UI线程的线程中-因此跨线程异常

// get a reference to the form's sync-context
SynchronizationContext _sync = SynchronizationContext.Current;

_sync.Send((state) => {
  // code to modify UI objects
}

您只能与创建控件(或窗体)的线程中的控件(或窗体)进行交互。由于您正在从第二个线程与表单交互,因此将抛出您的例外

要修复现有的问题,请查看表单上的Invoke或BeginInvoke方法——它们允许您传递将在表单线程上执行的委托(这称为“封送”)

更好:
使用计时器,而不是进入一段时间和睡眠。如果在Windows窗体名称空间中使用计时器,它将为您处理封送问题,因此您甚至不需要使用Invoke,因为必须在创建UI组件的同一线程上操作UI组件,因此会发生错误。您的后台工作人员正在另一个线程中操作

您可以使用
invokererequired
和回调来获取UI线程来完成这项工作

public void NudgeMe() {
    if( this.InvokeRequired ) {
        Action callBack = NudgeMe;
        this.Invoke( callBack );
    } else {

        int xCoord = this.Left;
        int yCoord = this.Top;


        int rnd = 0;


        Random RandomClass = new Random();

        for( int i = 0; i <= 500; i++ ) {
            rnd = RandomClass.Next( xCoord + 1, xCoord + 15 );
            this.Left = rnd;
            rnd = RandomClass.Next( yCoord + 1, yCoord + 15 );
            this.Top = rnd;
        }
        this.Left = xCoord;
        this.Top = yCoord;
    }
}
public void NudgeMe(){
if(this.invokererequired){
动作回调=轻推;
调用(回调);
}否则{
int xCoord=这个。左;
int yCoord=this.Top;
int rnd=0;
Random RandomClass=新的Random();

对于(int i=0;我读到:您可能不应该将整个过程放入
invoke
调用中。最好在调用时尽量少做,因为这样做时UI线程被阻塞。特别是在这种情况下,
for
循环正在进行大量增量更改,但因为只有一个
Invoke
call它们都是在每次完成后呈现的。
// get a reference to the form's sync-context
SynchronizationContext _sync = SynchronizationContext.Current;

_sync.Send((state) => {
  // code to modify UI objects
}
this.Invoke((MethodInvoker) delegate {
    this.Left = rnd;
});
public void NudgeMe() {
    if( this.InvokeRequired ) {
        Action callBack = NudgeMe;
        this.Invoke( callBack );
    } else {

        int xCoord = this.Left;
        int yCoord = this.Top;


        int rnd = 0;


        Random RandomClass = new Random();

        for( int i = 0; i <= 500; i++ ) {
            rnd = RandomClass.Next( xCoord + 1, xCoord + 15 );
            this.Left = rnd;
            rnd = RandomClass.Next( yCoord + 1, yCoord + 15 );
            this.Top = rnd;
        }
        this.Left = xCoord;
        this.Top = yCoord;
    }
}