简体   繁体   English

C#Winforms使用while循环(不同线程)更改背景色

[英]C# Winforms change backcolor using a while loop (different thread)

I'm trying to change the back color of a textbox to monitor a change detect on an XBee. 我正在尝试更改文本框的背景色,以监视XBee上的更改检测。

I'm trying to do this by having a while loop running in the background reading the serialport every 0.5 seconds, then checking if the change detect has detected that it's on or off. 我试图通过在后台运行一次while循环,每0.5秒读取一次串行端口,然后检查更改检测是否已检测到它的打开或关闭来执行此操作。 The application works as expected even when this while loop runs. 即使运行while循环,该应用程序仍能按预期工作。

public void DoThisAllTheTime()
{
    while (true)
    {
        byte[] buffer = new byte[14];
        try
        {
            for (int i = 0; i < 600; i++)//to make sure I always get the latest frame
            {
                serialPort1.Read(buffer, 0, buffer.Length);
            }
        }

        catch (Exception)
        {
        }

        if (buffer[12] == 129)
        {
            textBox1.BackColor = System.Drawing.Color.Green;
        }

        if (buffer[12] == 128)
        {
            textBox1.BackColor = System.Drawing.Color.Red;
        }
  Thread.Sleep(500);
}    

} }

This gives an exception "cross thread operation not valid". 这给出了一个异常“跨线程操作无效”。 I suspect this is because the textbox is on a different thread that is not accessible, and that I have to invoke it. 我怀疑这是因为文本框位于无法访问的其他线程上,因此我必须调用它。

I have tried using tips both from this Looping Forever in a Windows Forms Application and this Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on topic, without any luck. 我尝试使用Windows窗体应用程序中此“ 永远循环”和此跨线程操作无效的技巧:控制'textBox1'是从不是在主题上创建的线程的线程中访问的 ,没有任何运气。 I rewrote parts of the code in the 2nd link to try to fit my needs (removing string text etc.) but then I didn't have the correct amount of arguments. 我重写了第二个链接中的部分代码,以尝试满足我的需要(删除字符串文本等),但是随后我的参数数量不正确。

Am I taking the right approach here? 我在这里采用正确的方法吗? Am I right by assuming invoking is needed, and if yes, any help on how to do it? 我是否认为需要调用是对的,如果是,对执行该操作有任何帮助吗? Any input or guidelines would be very appreciated. 任何意见或指导方针将不胜感激。

You need to marshall the call to the UI thread: 您需要整理对UI线程的调用:

System.Threading.SynchronizationContext.Current.Post(theMethod, state);

See here: 看这里:

Run code on UI thread without control object present 在没有控制对象的情况下在UI线程上运行代码

Since you are using Winforms , and you are trying up update the control from another Thread , you will need use Invoke . 由于您正在使用Winforms ,并且您正在尝试从另一个Thread更新控件,因此需要使用Invoke

if (buffer[12] == 129)
{
    if (textBox1.InvokeRequired)
    {
        textBox1.Invoke((MethodInvoker)delegate
        {
            textBox1.BackColor = System.Drawing.Color.Green;
        });
    }
}

if (buffer[12] == 128)
{
    if (textBox1.InvokeRequired)
    {
        textBox1.Invoke((MethodInvoker)delegate
        {
            textBox1.BackColor = System.Drawing.Color.Red;
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM