多线程,线程池与BeginInvoke()

在WinForm中,很多情况下需要用到多线程,下面我来简单介绍一下多线程的基本用法。

1.线程。

(1)线程的初始化

Thread t = new Thread(new ThreadStart(ThreadProc));

其中,ThreadStart是一个系统定义的委托,ThreadProc是一个方法的名称,其签名与ThreadStart一样。

线程的启动:

(2)t.Start();

这样子,ThreadProc方法就会执行了。t 默认是一个非主线程,并且是一个前台线程。

(3)主线程等待子线程结束后再继续运行:

t.Join();

这个方法的意思是,主线程暂时挂起,等待线程t运行结束以后,主线程再激活,继续运行。

(4)当前线程休眠:

System.Threading.Thread.Sleep(time);
//time表示当前线程挂起的毫秒数。

2.线程池。

由于新增线程的开销是非常大的,所以,如果这个任务不是十分紧急且重要的话,不妨使用CRL线程池。CRL线程池是 .net 的一种分配线程的机制。它会根据任务量自动分配线程,并且是线程的利用率最大化,从而减小性能开销。

(1)想线程池队列中添加任务:

ThreadPool.QueueUserWorkItem(new WaitCallback(myFunction));

其中,QueueUserWorkItem方法是ThreadPool的静态方法,其作用是向当前进程的线程池队列中添加一个任务,他的参数是一个WaitCallBack委托的对象。WaitCallBack是系统定义的一个委托,其签名如下,

public delegate void WaitCallback(object state);

这就将MyFunction这个方法作为一个线程,添加到了线程池中,等待线程池的调用。

3.Invoke() 和 BeginInvoke() 方法。

大家都知道,不同的线程之间,程序和数据时互不干扰的。但是,在WinForm中,如果其他线程想要在执行完毕后,将其结果显示到UI界面上的话,程序就会出现异常,大概意思就是说,某控件不是在该线程中创建的,所以该线程不能访问器句柄(即对象,本质是一个指针)。那么,怎么解决这个问题呢?其实,这些问题,微软早就考虑到了。Control类中有Invoke() 和 BeginInvoke() 方法,他们就是用来处理其他线程访问UI线程数据的。我现在给大家写一个例子,让界面的一个label一直显示当前时间,并不断刷新。

首先,打开一个WinForm程序,往窗体上拖一个label。

然后添加命名空间 Using System.Threading ;

在把下面的代码写到Form1.cs中

        /// <summary>
        /// 这个方法实现更新label,让它显示当前时间
        /// </summary>
        /// <param name="o"> 这里的这个参数没有意义,只是为了符合某个委托的签名</param>
      private void ShowTime(object o)
        {
            while (true)
            {
                BeginInvoke(new Action(() => { label1.Text = "当前时间:" + DateTime.Now.ToString(); }));
                Thread.Sleep(1000);
            }
        }

但是,怎么让label一直更新呢,这就需要再开一个线程,我们不妨利用线程池。

我们注册一个Form1的Load事件,然后在这个事件中写下下一行代码:

ThreadPool.QueueUserWorkItem(new WaitCallback(ShowTime));

好了,下面这个功能就做好了。

下面,我解释一下里面的一些东西。

BeginInvoke是Control类的一个方法,其参数是一个WaitCallBack委托的对象。

new Action(() => { label1.Text = "当前时间:" + DateTime.Now.ToString(); }),这是一个匿名方法,Action的参数是一个Lambda表达式。Action是系统定义的一个委托,其签名如下:

public delegate void Action();即空返回值,空参数。

时间: 2024-10-07 02:03:17

多线程,线程池与BeginInvoke()的相关文章

C#多线程--线程池(ThreadPool)

先引入一下线程池的概念: 百度百科:线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中.如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙.如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值.超过最大值的线程可以排队,但他们要等到其他线程

ExecutorService 建立多线程线程池的步骤

ExecutorService 建立多线程线程池的步骤: 线程池的作用: 线程池作用就是限制系统中执行线程的数量. 根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少了浪费了系统资源,多了造成系统拥挤效率不高.用线程池控制线程数量,其他线程排队等候.一个任务执行完毕,再从队列的中取最前面的任务开始执行.若队列中没有等待进程,线程池的这一资源处于等待.当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了:否则进入等待队列. 为什么要用线程池: 1.减少了创建和

Java多线程——线程池

系统启动一个新线程的成本是比较高的,因为它涉及到与操作系统的交互.在这种情况下,使用线程池可以很好的提供性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池. 与数据库连接池类似的是,线程池在系统启动时即创建大量空闲的线程,程序将一个Runnable对象传给线程池,线程池就会启动一条线程来执行该对象的run方法,当run方法执行结束后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个Runnable对象的run方法. 除此之外,使用线程池可以有效地控制系统

java多线程--线程池的使用

程序启动一个新线程的成本是很高的,因为涉及到要和操作系统进行交互,而使用线程池可以很好的提高性能,尤其是程序中当需要创建大量生存期很短的线程时,应该优先考虑使用线程池. 线程池的每一个线程执行完毕后,并不会死亡,会再次回到线程池中变成空闲状态,等待下一个对象来调用,类比于数据库连接池.JDK1.5以后,java内置线程池. JDK5新增了一个Executors工厂类来产生线程池,通过查文档我们发现,产生线程池很多方法,常用的有以下几个方法: public static ExecutorServi

26、Java并发性和多线程-线程池

以下内容转自http://ifeve.com/thread-pools/: 线程池(Thread Pool)对于限制应用程序中同一时刻运行的线程数很有用.因为每启动一个新线程都会有相应的性能开销,每个线程都需要给栈分配一些内存等等. 我们可以把并发执行的任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程.只要池里有空闲的线程,任务就会分配给一个线程执行.在线程池的内部,任务被插入一个阻塞队列(Blocking Queue ),线程池里的线程会去取这个队列里的任务.当一个新任务插入

跟我学Java多线程——线程池与堵塞队列

前言 上一篇文章中我们将ThreadPoolExecutor进行了深入的学习和介绍,实际上我们在项目中应用的时候非常少有直接应用ThreadPoolExecutor来创建线程池的.在jdk的api中有这么一句话"可是,强烈建议程序猿使用较为方便的 Executors 工厂方法Executors.newCachedThreadPool()(无界线程池,能够进行自己主动线程回收).Executors.newFixedThreadPool(int)(固定大小线程池)和Executors.newSing

跟我学Java多线程——线程池与阻塞队列

前言 上一篇文章中我们将ThreadPoolExecutor进行了深入的学习和介绍,实际上我们在项目中应用的时候很少有直接应用ThreadPoolExecutor来创建线程池的,在jdk的api中有这么一句话"但是,强烈建议程序员使用较为方便的 Executors 工厂方法Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收).Executors.newFixedThreadPool(int)(固定大小线程池)和Executors.newSingleT

多线程 线程池 守护线程

守护线程只是个概念问题,一句话可以总结(不知道总结的对不对^_^); 当所有用户线程都结束的时候,守护线程也就结束了,当有用户线程存在的时候,守护线程就是一个普通线程. main线程不可以设置成守护线程,应为只有在线程调用start方法前,才可以设置线程为守护线程,main线程是jvm创建的 多线程以及线程池的问题 import java.io.DataInputStream; import java.io.File; import java.io.FileOutputStream; impor

线程--多线程线程池

最近在深入学习多线程方面的知识,关于多线程,我们在开发中常用到的是用线程池去处理各种业务逻辑 譬如 一段大的集合对象,想要快速的插入到数据库,我们可以循环插入,也可以用线程池的方式来同时插入 或者是 调用接口,每个对象一次次的调用接口 ,也可以使用多线程来调用接口 下面这段代码 可以处理这个问题 package com.demo; import java.util.LinkedList; import java.util.List; import java.util.concurrent.Exe