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

时间:2016-04-17 21:15:23

标签: c# multithreading winforms

我试图更改文本框的背景颜色以监控XBee上的更改检测。

我尝试通过在后台运行while循环每隔0.5秒读取一次串行端口,然后检查更改检测是否检测到它已打开或关闭来尝试这样做。即使这个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);
}    

}

这给出了异常&#34;交叉线程操作无效&#34;。我怀疑这是因为文本框位于不可访问的不同线程上,我必须调用它。

我尝试过使用此Looping Forever in a Windows Forms Application提示 这个Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on话题,没有任何运气。我重写了第二个链接中的部分代码以尝试满足我的需求(删除字符串文本等),但后来我没有正确数量的参数。

我在这里采取了正确的方法吗?我是否正确假设需要调用,如果是的话,是否有任何关于如何做的帮助?任何意见或指导都将非常感激。

2 个答案:

答案 0 :(得分:0)

您需要对UI线程的调用进行编组:

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

见这里:

Run code on UI thread without control object present

答案 1 :(得分:0)

由于您使用的是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;
        });
    }
}