[轉]C#子執行緒更新UI控制元件的方法例項總結
[我的評論:之前專案做的C#客戶端對於多執行緒修改UI使用的就是這個,找了好些時間才找到,其他很多都是沒有再函式中直接使用Action<>放置delegate的,而是在全域性下先放一個delegate的宣告,很頭疼,特轉]
[來源:http://www.jb51.net/article/55186.htm (來源也標名轉載,可能不是最初來源)]
這篇文章主要介紹了C#子執行緒更新UI控制元件的方法,在桌面應用程式中控制UI介面有著不錯的實用價值,需要的朋友可以參考下
本文例項總結了C#子執行緒更新UI控制元件的方法,對於桌面應用程式設計的UI介面控制來說非常有實用價值。分享給大家供大家參考之用。具體分析如下:
一般在winform C/S程式中經常會在子執行緒中更新控制元件的情況,桌面程式UI執行緒是主執行緒,當試圖從子執行緒直接修改控制元件屬性時會出現“從不是建立控制元件的執行緒訪問它”的異常提示。
跨執行緒更新UI控制元件的常用方法有兩種:
1.使用控制元件自身的invoke/BeginInvoke方法
2.使用SynchronizationContext的Post/Send方法更新
具體實現如下:
1.使用控制元件自身的invoke/BeginInvoke方法
Control類實現了ISynchronizeInvoke 介面,我們看該介面的定義:
Control類的invoke方法有兩個實現
Object Invoke(Delegate); //在擁有此控制元件的基礎視窗控制代碼的執行緒上執行指定的委託
Object Invoke(Delegate,Object[] );
可以看出繼承Control類的UI控制元件都可以使用Invoke方法非同步更新。以下程式碼段實現在子執行緒中更新Label控制元件的Text屬性
private void button6_Click(object sender, EventArgs e) { Thread demoThread =new Thread(new ThreadStart(threadMethod)); demoThread.IsBackground = true; demoThread.Start();//啟動執行緒 } void threadMethod() { Action<String> AsyncUIDelegate=delegate(string n){label1.Text=n;};/<span style="font-family: Arial, Helvetica, sans-serif;">/定義一個委託</span> label1.Invoke(AsyncUIDelegate,new object[]{"修改後的label1文字"}); }
2.使用SynchronizationContext的Post/Send方法更新
SynchronizationContext類在System.Threading命令空間下,可提供不帶同步的自由執行緒上下文,其中Post方法簽名如下:
public virtual void Post(SendOrPostCallback d,Object state) //將非同步訊息排程到一個同步上下文
可以看出我們要非同步更新UI控制元件,第一是要獲取UI執行緒的上下文了,第二就是呼叫post方法了,程式碼實現:
SynchronizationContext _syncContext = null;
private void button6_Click(object sender, EventArgs e)
{
Thread demoThread =new Thread(new ThreadStart(threadMethod));
demoThread.IsBackground = true;
demoThread.Start();//啟動執行緒
}
//窗體建構函式
public Form1()
{
InitializeComponent();
//獲取UI執行緒同步上下文
_syncContext = SynchronizationContext.Current;
}
private void threadMethod()
{
_syncContext.Post(SetLabelText, "修改後的文字");//子執行緒中通過UI執行緒上下文更新UI
}
private void SetLabelText(object text)
{
this.lable1.Text = text.ToString();
}
希望本文所述對大家的C#程式設計有所幫助