Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Windows窗体中的线程错误_C#_Winforms - Fatal编程技术网

C#Windows窗体中的线程错误

C#Windows窗体中的线程错误,c#,winforms,C#,Winforms,我收到了这个错误: “System.InvalidOperationException”类型的未处理异常 发生在System.Windows.Forms.dll中 其他信息:跨线程操作无效:控件 “红灯”是从创建它的线程以外的线程访问的 开 红灯和绿灯都是图片框。 基本上,我希望它能做的就是每秒钟在每张图片之间交替。 我在这个网站上搜索了类似的错误,我看到它与“调用”有关,但我甚至不知道那是什么,有人能启发我吗 using System; using System.Collections.Gen

我收到了这个错误:

“System.InvalidOperationException”类型的未处理异常 发生在System.Windows.Forms.dll中

其他信息:跨线程操作无效:控件 “红灯”是从创建它的线程以外的线程访问的 开

红灯和绿灯都是图片框。 基本上,我希望它能做的就是每秒钟在每张图片之间交替。 我在这个网站上搜索了类似的错误,我看到它与“调用”有关,但我甚至不知道那是什么,有人能启发我吗

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace EMCTool
{
    public partial class EMCTool_MainForm : Form
    {
        bool offOn = false;

        public EMCTool_MainForm()
        {
            InitializeComponent();
        }

        private void EMCTool_MainForm_Load(object sender, EventArgs e)
        {
            System.Threading.Timer timer = new System.Threading.Timer(new System.Threading.TimerCallback(timerCallback), null, 0, 1000);
        }

        private void timerCallback(object obj)
        {
            if (offOn == false)
            {
                Redlight.Show();
                offOn = true;
            }
            else
            {
                Greenlight.Show();
                offOn = false;
            }
        }
    }
}

当您尝试从未创建UI元素的任何线程更新UI元素时,会出现跨线程错误

Windows窗体中的控件绑定到特定线程,并且不是线程安全的。因此,如果从不同的线程调用控件的方法,则必须使用控件的某个调用方法将调用封送到适当的线程。此属性可用于确定是否必须调用invoke方法,如果您不知道哪个线程拥有控件,则该属性非常有用

参考更多

试试这个。这个对我很好用

   if (pictureBoxname.InvokeRequired)
                    pictureBoxname.Invoke(new MethodInvoker(delegate
                    {
          //access picturebox here
                    }));
                else
        {

  //access picturebox here
}   

另一种解决方案是使用System.Timers.Timer,它具有SynchronizingObject属性,因此设置该属性,它将工作:

timer.SynchronizingObject = This

或者使用System.Windows.Forms.Timer,因为它不会引发异常(它会在UI线程上引发Tick事件)。

在WinForms项目中,最好使用
System.Windows.Forms.Timer
,因为它会自动调用UI线程上的
Tick
事件:

private System.Windows.Forms.Timer _timer;

private void EMCTool_MainForm_Load(object sender, EventArgs e)
{
    _timer = new System.Windows.Forms.Timer { Interval = 1000 };
    _timer.Tick += Timer_Tick;
    _timer.Start();
}

private void Timer_Tick(object sender, EventArgs e)
{
    if (offOn) {
        Greenlight.Show();
    } else {
        Redlight.Show();
    }
    offOn = !offOn;
}

哦,好吧,这东西是怎么工作的,它对我有什么作用?编辑:我已经测试过了,并且成功了。Invoke方法将UI相关的处理委托给创建它的线程,即UI线程。@user1880591它将您的调用发送到创建控件的线程,该线程执行该任务。调用是否使用了大量资源和性能?我觉得我必须使用invoke来处理我在窗体上放置的所有内容。@user1880591使用Windows窗体计时器而不是System.Threading.Timer将首先避免所有跨线程操作。。。