[转]C#利用委托跨线程更新UI数据

在使用C#的过程中,难免会用到多线程,而用多线程之后,线程如何与界面交互则是一个非常头疼的问题。其实不仅仅是界面,一般情况下,我们往往需要获得线程的一些信息来确定线程的状态。比较好的方式是用委托实现,看例子:

 class TestClass
 {
        //声明一个delegate(委托)类型:testDelegate,该类型可以搭载返回值为空,参数只有一个(long型)的方法。
       public delegate void testDelegate(long i); 

       //声明一个testDelegate类型的对象。该对象代表了返回值为空,参数只有一个(long型)的方法。它可以搭载N个方法。
       public testDelegate mainThread; 

       /// <summary>
       /// 测试方法
       /// </summary>
       public void testFunction()
       {
            long i = 0;
            while(true)
           {
                i++;
                mainThread(i); //调用委托对象
                Thread.Sleep(1000);  //线程等待1000毫秒
            }
        } }

  winform界面代码:

1. /// <summary>
2. /// 按钮单击事件
3. /// </summary>
4. /// <param name="sender"></param>
5. /// <param name="e"></param>
6. private void button1_Click(object sender, EventArgs e)
7. {
8.     //创建TestClass类的对象
9.     TestClass testclass = new TestClass();
10.
11.     //在testclass对象的mainThread(委托)对象上搭载两个方法,在线程中调用mainThread对象时相当于调用了这两个方法。
12.     testclass.mainThread = new TestClass.testDelegate(refreshLabMessage1);
13.     testclass.mainThread += new TestClass.testDelegate(refreshLabMessage2);
14.
15.     //创建一个无参数的线程,这个线程执行TestClass类中的testFunction方法。
16.     Thread testclassThread = new Thread(new ThreadStart(testclass.testFunction));
17.     //启动线程,启动之后线程才开始执行
18.     testclassThread.Start();
19. }

  

21. /// <summary>
22. /// 在界面上更新线程执行次数
23. /// </summary>
24. /// <param name="i"></param>
25. private void refreshLabMessage1(long i)
26. {
27.     //判断该方法是否被主线程调用,也就是创建labMessage1控件的线程,当控件的InvokeRequired属性为ture时,说明是被主线程以外的线程调用。如果不加判断,会造成异常
28.     if (this.labMessage1.InvokeRequired)
29.     {
30.         //再次创建一个TestClass类的对象
31.         TestClass testclass = new TestClass();
32.         //为新对象的mainThread对象搭载方法
33.         testclass.mainThread = new TestClass.testDelegate(refreshLabMessage1);
34.         //this指窗体,在这调用窗体的Invoke方法,也就是用窗体的创建线程来执行mainThread对象委托的方法,再加上需要的参数(i)
35.         this.Invoke(testclass.mainThread,new object[] {i});
36.     }
37.     else
38.     {
39.         labMessage1.Text = i.ToString();
40.     }
41. }
42.
43. /// <summary>
44. /// 在界面上更新线程执行次数
45. /// </summary>
46. /// <param name="i"></param>
47. private void refreshLabMessage2(long i)
48. {
49.     //同上
50.     if (this.labMessage2.InvokeRequired)
51.     {
52.         //再次创建一个TestClass类的对象
53.         TestClass testclass = new TestClass();
54.         //为新对象的mainThread对象搭载方法
55.         testclass.mainThread = new TestClass.testDelegate(refreshLabMessage2);
56.         //this指窗体,在这调用窗体的Invoke方法,也就是用窗体的创建线程来执行mainThread对象委托的方法,再加上需要的参数(i)
57.         this.Invoke(testclass.mainThread, new object[] { i });
58.     }
59.     else
60.     {
61.         labMessage2.Text = i.ToString();
62.     }
63. }

  

时间: 2024-12-24 08:21:11

[转]C#利用委托跨线程更新UI数据的相关文章

C# Winform 跨线程更新UI控件常用方法总结(转)

出处:http://www.tuicool.com/articles/FNzURb 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常.处理跨线程更新Winform UI控件常用的方法有4种: 1. 通过UI线程的SynchronizationContext的Post/Send方法更新: 2. 通过UI控件的Invoke/BegainInvoke方法更新: 3. 通过BackgroundWorker取代Thre

C# Winform 跨线程更新UI控件常用方法汇总

C# Winform 跨线程更新UI控件常用方法汇总 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常.处理跨线程更新Winform UI控件常用的方法有4种:1. 通过UI线程的SynchronizationContext的Post/Send方法更新:2. 通过UI控件的Invoke/BeginInvoke方法更新: 3. 通过BackgroundWorker取代Thread执行异步操作:4. 通过设置窗体

C# 委托 / 跨线程访问UI / 线程间操作无效: 从不是创建控件“Form1”的线程访问它

C# 委托 / 跨线程访问UI /  线程间操作无效: 从不是创建控件"Form1"的线程访问它 网上的代码都比较复杂,还是这个简单 见代码, 简易解决办法: 主窗体代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; usi

(转).NET 4.5中使用Task.Run和Parallel.For()实现的C# Winform多线程任务及跨线程更新UI控件综合实例

http://2sharings.com/2014/net-4-5-task-run-parallel-for-winform-cross-multiple-threads-update-ui-demo 在C# WINFORM的开发中,难免会遇到多线程的开发以提高程序的执行效率.自己刚才开始在做多线程的开发时也遇到了很多这方面的问题,比如:如何使用并实现多线程功能.跨线程更新UI控件等问题.还记得最初使用的是System.Threading命名空间下的Thread类来实现的: C# 1 2 3

NetworkComms网络程序开发笔记(二): 跨线程更新UI

跨线程更新UI的方法也很多 使用系统自带的 MethodInvoker 委托也不失为一个好方法 举例1 void NetworkComms_ConnectionClosed(Connection conn) { if (this.InvokeRequired) { MethodInvoker del = delegate { NetworkComms_ConnectionClosed(conn); }; this.Invoke(del); return; } textBox1.Text = "&

C#多线程与UI响应 跨线程更新UI

最近在写一个TCP通信程序,自定义了一个通信类TCPclient,用于客户端异步接收和发送网络消息. TCPclient中定义了一个接收到新的网络消息事件: 1 //收到新消息事件 2 public delegate void receiveNewNetworkMsgHandler( string networkMSG); 3 public event receiveNewNetworkMsgHandler receiveNewNetworkMsg; 在外部的窗体中订阅了此事件: void th

使用Task来实现跨线程更新UI

public partial class Form1 : Form { public Form1() { InitializeComponent(); var task = Task.Factory.StartNew(() => { for (int i = 0; i < 9999; i++) { UpdateText("测试" + i); Thread.Sleep(1000); } }); } public void UpdateText(string text) { i

C#子线程更新UI控件的方法总结

http://blog.csdn.net/jqncc/article/details/16342121 在winform C/S程序中经常会在子线程中更新控件的情况,桌面程序UI线程是主线程,当试图从子线程直接修改控件属性时会出现“从不是创建控件的线程访问它”的异常提示. 跨线程更新UI控件的常用方法有两种: 1.使用控件自身的invoke/BeginInvoke方法 2.使用SynchronizationContext的Post/Send方法更新 1.使用控件自身的invoke/BeginIn

Android子线程更新UI主线程方法之Handler

背景: 我们开发应用程序的时候,处于线程安全的原因子线程通常是不能直接更新主线程(UI线程)中的UI元素的,那么在Android开发中有几种方法解决这个问题,其中方法之一就是利用Handler处理的. 下面说下有关Handler相关的知识. 多线程一些基础知识回顾:在介绍Handler类相关知识之前,我们先看看在Java中是如何创建多线程的方法有两种:通过继承Thread类,重写Run方法来实现通过继承接口Runnable实现多线程 具体两者的区别与实现,看看这篇文章中的介绍:http://de