C#子線程更新UI控件的方法總結


http://blog.csdn.net/jqncc/article/details/16342121

 

在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屬性

 

[csharp] view plain copy
  1. private void button6_Click(object sender, EventArgs e)  
  2. {  
  3.      Thread demoThread =new Thread(new ThreadStart(threadMethod));  
  4.      demoThread.IsBackground = true;  
  5.      demoThread.Start();//啟動線程  
  6. }  
  7.   
  8.  void threadMethod()  
  9.  {   
  10.       Action<String> AsyncUIDelegate=delegate(string n){label1.Text=n;};/<span style="font-family: Arial, Helvetica, sans-serif;">/定義一個委托</span>  
  11.       label1.Invoke(AsyncUIDelegate,new object[]{"修改后的label1文本"});  
  12.  }  


2.使用SynchronizationContext的Post/Send方法更新

SynchronizationContext類在System.Threading命令空間下,可提供不帶同步的自由線程上下文,其中Post方法簽名如下:

public virtual void Post(SendOrPostCallback d,Object state)    //將異步消息調度到一個同步上下文

可以看出我們要異步更新UI控件,第一是要獲取UI線程的上下文了,第二就是調用post方法了,代碼實現:

 

[csharp] view plain copy
    1. SynchronizationContext _syncContext = null;  
    2.   
    3. private void button6_Click(object sender, EventArgs e)  
    4. {  
    5.     Thread demoThread =new Thread(new ThreadStart(threadMethod));  
    6.     demoThread.IsBackground = true;  
    7.     demoThread.Start();//啟動線程  
    8. }  
    9.   
    10. //窗體構造函數     
    11. public Form1()  
    12. {  
    13.     InitializeComponent();  
    14.       //獲取UI線程同步上下文  
    15.     _syncContext = SynchronizationContext.Current;  
    16. }  
    17.   
    18. private void threadMethod()  
    19. {  
    20.      _syncContext.Post(SetLabelText, "修改后的文本");//子線程中通過UI線程上下文更新UI  
    21. }  
    22.    
    23. private void SetLabelText(object text)  
    24. {  
    25.     this.lable1.Text = text.ToString();  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM