首页  编辑  

C# 中线程同步更新界面UI最简单和优雅的方法

Tags: /C#/进程、线程处理/   Date Created:
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)
{
    // update UI code here,更新UI界面的代码
}
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)
{
	//// 这里对界面GUI控件进行常规的操作
}
然后可以在线程的代码中或者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);
				}));
			}
		}
	}
}