0


C# Winform跨线程更新UI控件的方法

1、通过SynchronizationContext的Post/Send方法
主要原理是:在线程执行过程中,需要更新到UI控件上的数据不再直接更新,而是通过UI线程上下文的Post/Send方法,将数据以异步/同步消息的形式发送到UI线程的消息队列;UI线程收到该消息后,根据消息是异步消息还是同步消息来决定通过异步/同步的方式调用SetLabel1Post方法直接更新自己的控件了。
从本质讲,向UI线程发送的消息并是不简单数据,而是一条委托调用命令。
1.1、获取UI线程同步上下文(在窗体构造函数或FormLoad事件中)

SynchronizationContext synchronizationContext =null;System.Timers.Timer timer =newSystem.Timers.Timer();publicForm1(){InitializeComponent();
   synchronizationContext = SynchronizationContext.Current;
   timer.Interval +=100;
   timer.Elapsed += Timer_Elapsed;
   timer.Start();}

1.2、定义更新UI控件的方法

privatevoidSetLabel1Post(object text){this.label1.Text = text.ToString();}

1.3、在定时线程中调用更新UI控件的方法

Boolean flag =false;privatevoidTimer_Elapsed(object sender,System.Timers.ElapsedEventArgs e){string str;if(flag){
      str ="数据回读值:0x0001";
      flag =false;}else{
      str ="寄存器回读值:0x0088";
     flag =true;}
   synchronizationContext.Post(SetLabel1Post, str);}

2、通过Invoke/BeginInvoke方法
本质上还是把线程中要提交的消息,通过控件句柄调用委托交到UI线程中去处理。
2.1、定义定时线程

System.Timers.Timer timer =newSystem.Timers.Timer();publicForm1(){InitializeComponent();
    timer.Interval +=100;
    timer.Elapsed += Timer_Elapsed;
   timer.Start();}

2.2、采用跨线程委托

privatevoidSetLabelText(Label label,string text){try{if(label.InvokeRequired){MethodInvoker mi =delegate(){
             label.Text = text;};
         label.Invoke(mi);}else{
          label.Text = text;}}catch(Exception e){
        Console.WriteLine(e.Message);}}

2.3、在定时处理函数更新控件

Boolean flag =false;privatevoidTimer_Elapsed(object sender,System.Timers.ElapsedEventArgs e){string str;if(flag){
      str ="数据回读值:0x0001";
      flag =false;}else{
     str ="寄存器回读值:0x0086";
     flag =true;}SetLabelText(label2, str);}

2.4、解决出现“访问已释放句柄“的异常的方法

while(!this.label3.IsHandleCreated){if(this.label3.Disposing ||this.label3.IsDisposed)return;}

3、通过设置窗体属性,取消非法跨线程调用检查来避免"线程间操作无效异常"
通过设置该属性为false简单的屏蔽了该异常(非线程安全,建议不使用)。

publicForm1(){InitializeComponent();//取消非法跨线程调用检查
    Control.CheckForIllegalCrossThreadCalls =false;}
标签: ui c# 跨线程

本文转载自: https://blog.csdn.net/qq_27474555/article/details/127427195
版权归原作者 大浪淘沙胡 所有, 如有侵权,请联系我们删除。

“C# Winform跨线程更新UI控件的方法”的评论:

还没有评论