How to update UI from thread in C#?
1. define delegate when necessary:
public delegate void DataReceivedDelegate(byte[] bBuffer, int len);
2. write a delegate:
public void CallDataReceived(byte[] bBuffer, int len)
{
}
3. In thread, invoke the delegate, 在线程当中,调用委托:
threadGetComData = new System.Threading.Thread(new ThreadStart(ThreadGetComData));
threadGetComData.Start();
private void ThreadGetComData()
{
serialport.Write(data, 0, len);
serialport.Read(data, 0, serialport.BytesToRead)
Invoke(new DataReceivedDelegate(CallDataReceived), new object[] { buf, len });
}
在C#中,如果要在线程当中更新界面UI,比较麻烦的,一般采用控件的Invoke方法,例如Memo.Invoke或者BeginInvoke等来实现界面更新,但如果对大堆控件要更新就麻烦了。
如果你在线程当中,使用一个Form,或者通过Deletegate来调用,可以用下面的方法实现:
在Form中,写上一个代码:
private void SafeOnCommand(Object param1, Object Param2)
{
}
然后可以在线程的代码中或者Delegate中使用form的BeginInvoke即可:
this.BeginInvoke(new MethodInvoker(() => SafeOnCommand(Param1, Param2)));
完整例子或者代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
new Thread(() => ThreadTask()).Start();
}
private void SafeUpdateUI(int progress)
{
progressBar1.Value = progress;
Text = "Loading: " + progress.ToString() + "%";
}
private void ThreadTask()
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(100);
this.BeginInvoke(new MethodInvoker(() =>
{
SafeUpdateUI(i);
}));
}
}
}
}