我正在使用mod总线协议从电路板上检索数据。现在我想一直以窗口形式更新数据。但标签只在我点击按钮时更新,我的编码有问题吗?
private void Call(){
do
{
RequestData(); //get data from mod bus
run(a.ToString());
} while (operation);
}
delegate void CallMethod(string Data);
private void run(string data) {
if (this.labelO2.InvokeRequired)
{
SetRichBoxCallBack d = new SetRichBoxCallBack(run);
this.Invoke(d, new object[] { data });
}
else {
labelO2.Text = data;
}
}
Thread thread;
private void button1_Click(object sender, EventArgs e)
{
thread = new Thread(new ThreadStart(Call));
thread.Start();
}
public void RequestData()
{
if (WriteSerialPort(setMessage, 0, 8))
{
Thread.Sleep(1000);
for (i = 0; i < 19; i++)
{
MM[i] = (byte)serialPortBoard.ReadByte();
}
a = MM[11] << 8 | MM[12];
b = (int)MM[13] << 8 | MM[14];
}
}
答案 0 :(得分:0)
对UI更新的调用应该包含在InvokeRequired ...
模式中 - 而不是从端口获取数据。此外,InvokeRequired...
模式也缺失。
delegate void UIUpdate(object a, object b);
public void RequestData() {
...
// set type and real value here ;)
object a = null, b = null;
var call = new UIUpdate((pa,pb) => {
labelBin.Text = pa.ToString();
labelO2.Text = pb.ToString();
});
if (this.InvokeRequired) {
this.Invoke(call, a, b);
} else {
call.Invoke(a, b);
}
}
private void button1_Click(object sender, EventArgs e) {
new Thread(() => {
do {
RequestData(); // get the data from mod bus protocol
} while (operation);
}).Start();
}
修改强>
此外,应该只有一个读者线程;哪个会读;不要在一个线程中写/读。读者线程应该在表单加载或表单构造函数中启动。
WriteSerialPort(setMessage, 0, 8)
应该在按钮点击时直接调用,而read应该始终在单个(单独)线程中。