我想用串口将单片机的温度值送到C#接口,并在Label.Content
上显示温度。这是我的微控制器代码:
while(1) {
key_scan(); // get value of temp
if (Usart_Data_Ready())
{
while(temperature[i]!=0)
{
if(temperature[i]!=' ')
{
Usart_Write(temperature[i]);
Delay_ms(1000);
}
i = i + 1;
}
i =0;
Delay_ms(2000);
}
}
我的C#代码是:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
txt += serialPort1.ReadExisting().ToString();
textBox1.Text = txt.ToString();
}
但出现异常“跨线程操作无效:控件'textBox1‘是从上创建的线程以外的线程访问的”请告诉我如何从我的微控制器获取温度字符串并消除此错误!
发布于 2012-05-28 00:15:15
在您的serialPort1_DataReceived
方法中接收的数据来自另一个线程上下文,而不是UI线程,这就是您看到此错误的原因。
要解决此问题,您必须使用MSDN文章中描述的调度程序:
How to: Make Thread-Safe Calls to Windows Forms Controls
因此,不要直接在serialport1_DataReceived
方法中设置text属性,请使用以下模式:
delegate void SetTextCallback(string text);
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
所以在你的例子中:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
txt += serialPort1.ReadExisting().ToString();
SetText(txt.ToString());
}
发布于 2013-04-05 18:12:49
我不知道这是否足够好,但是我做了一个静态的ThreadHelperClass类,并按照下面的.Now实现了它,我可以很容易地设置各种控件的文本属性,而不需要太多的编码。
public static class ThreadHelperClass
{
delegate void SetTextCallback(Form f, Control ctrl, string text);
/// <summary>
/// Set text property of various controls
/// </summary>
/// <param name="form">The calling form</param>
/// <param name="ctrl"></param>
/// <param name="text"></param>
public static void SetText(Form form, Control ctrl, string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (ctrl.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
form.Invoke(d, new object[] { form, ctrl, text });
}
else
{
ctrl.Text = text;
}
}
}
使用以下代码:
private void btnTestThread_Click(object sender, EventArgs e)
{
Thread demoThread =
new Thread(new ThreadStart(this.ThreadProcSafe));
demoThread.Start();
}
// This method is executed on the worker thread and makes
// a thread-safe call on the TextBox control.
private void ThreadProcSafe()
{
ThreadHelperClass.SetText(this, textBox1, "This text was set safely.");
ThreadHelperClass.SetText(this, textBox2, "another text was set safely.");
}
发布于 2012-11-27 03:27:43
你可以简单地做到这一点。
TextBox.CheckForIllegalCrossThreadCalls = false;
https://stackoverflow.com/questions/10775367
复制相似问题