上一节主要是对线程有一个具体的介绍,同时也介绍了线程调用无参函数的方法,这一节主要介绍线程调用有参甚至是多参函数,同时也会进一步的介绍线程池。
先介绍线程调用有参函数
一、调用有一个参数的函数
static void Main(string[] args)
{
//标记显示主线程ID
Console.WriteLine("主线程的ID:" + Thread.CurrentThread.ManagedThreadId);
//如果线程要调用有参函数,这时线程的构造函数的参数应为一个ParameterizedThreadStart的实例对象,函数参数必须为Object类型
Thread thread = new Thread(new ParameterizedThreadStart(ParamMethod));
thread.Start("Olive");
//同时还可以用lambda表达式进行传值,这个时候可以传任意类型的值和任意多个参数
Thread thread1=new Thread(()=>ParamMethod("Olive");
Thread1.Start();
Console.ReadKey();
}
private static void ParamMethod(object name)
{
Console.WriteLine("当前的线程ID:" + Thread.CurrentThread.ManagedThreadId);//标记显示当前线程ID
Console.WriteLine("Hello World!My gril's name is:" + name);
}
效果如图
二、调用有多个参数的构造函数
线程调用含有多个参数的函数主要有以下几种方法。
1、将所需要的传递的数据封装成一个类
例如:
先建一个类,将要传递的信息包含其中
public class Student
{
public string Name
{ get; set; }
public string Sex
{ get; set; }
public int Age
{ get; set; }
public string Address
{ get; set;}
}
具体的实现如下:
static void Main(string[] args)
{
Student student = new Student()
{
Name = "Olve",
Sex = "女",
Age = 22,
Address = "北京"
};
Console.WriteLine("主线程的ID:" + Thread.CurrentThread.ManagedThreadId);//标记显示主线程ID
Thread thread = new Thread(new ParameterizedThreadStart(ParamMethod));
thread.Start(student);
Console.ReadKey();
}
private static void ParamMethod(object obj)
{
Console.WriteLine("当前的线程ID:" + Thread.CurrentThread.ManagedThreadId);//标记显示当前线程ID
Student student = (Student)obj;//因为传递的参数为Object类型的这里要强制转换下
Console.WriteLine("Hello World!My gril's name is " + student.Name);
Console.WriteLine("and her age is "+student.Age);
Console.WriteLine("Now,She is in "+student.Address);
}
2、使用lambda表达式传递多个参数
通过使用lambda表达式传递多个参数和传递一个参数是一样的
具体看代码
Main函数里代码:
Thread thread=new Thread(()=>TestShow("Olive","22","北京"));
thread.Start();
Private static void (object name,object age,object address)
{
Console("My girl's name is"+name+"Age is"+age+"Address is"+address);
}
效果如下图:
介绍完了线程调用有参函数的传参,下面再介绍下线程池。
创建线程是需要时间的,每个线程也会被分配一些内存。许多应用程序一般都使用多个线程进行协同工作,为了简化对这些线程的管理,.NET框架为每一个进程提供了一个线程池,使应用程序能够根据需要来有效地利用多个线程。线程池线程都是后台线程。每个线程都使用默认堆栈大小,以默认的优先级运行,并处于多线程单元中。
在这里首先要感谢下上一节中给我指出错误的兄弟,实在是抱歉由于我的一时疏忽,将通过Thread类创建的线程写成是后台线程,这确实是大错特错的。先介绍下什么是前台线程、什么是后台线程。
前台线程:线程默认为前台线程,只要有一个前台线程在运行,程序就一直运行、存活。
后台线程:当所有的前台线程结束之后,程序就会结束,不论后台线程是否运行结束,程序都会将后台线程给Kill掉。
在默认情况下,用Thread 类创建的线程都是前台线程。线程池中的线程总是后台线程.
在用Thread类创建线程时,可以设置属性IsBackground,以确定该线程是(false)前台线程还是(true)后台线程。一般使用时多将线程设置为后台线程,这样在程序关闭时可以立即释放资源,有时候我们会发现明明一个程序已经关闭了,但是查看任务管理器发现它还在占用一些内存,就是因为还有些前台线程没有执行完毕的缘故。
线程池特别适合于执行一些需要多个线程的任务。使用线程池能够优化这些任务的执行过程,从而提高吞吐量,它不仅能够使系统针对此进程优化该执行过程,而且还能够使系统针对计算机上的其他进程优化该执行过程。但是同时它也有一些限制比如:不能把线程池中的线程改为前台线程,不能给线程池中的线程设置优先级或名称,线程池中的线程只能用于时间较短的任务,如果用时较长,应使用Thread类创建实例。
下面介绍线程池的主要用法:
System.Threading.ThreadPool类实现了线程池,该类是一个静态类。最长用的是
ThreadPool.QueueUserWorkItem(WaitCallback waitcallback ,object state)
该函数有两个参数一个是WaitCallBack类型的委托,一个是状态,可以作为传递单个的参数,如果需要传递多个参数,可以先将参数封装成类,传递类对象。
ThreadPool.QueueUserWorkItem方法在线程池中创建一个线程池线程来执行指定的方法(用委托WaitCallback来表示),并将该线程排入线程池的队列等待执行
具体使用如下:
Main函数代码如下:
{
string s="Olive";
ThreadPool.QueueUserWorkItem(new WaitCallback(Count), s);
}
Private static Count(object name)
{
Console.WriteLine("Hello ! My Name is "+name);
}
每个进程都有且只有一个线程池。当进程启动时,线程池并不会自动创建。当第一次将回调方法排入队列(比如调用ThreadPool.QueueUserWorkItem方法)时才会创建线程池。
这一节就介绍到这里了,下一节会介绍线程的同步相关的知识。希望能对朋友们有一点帮助,如果有说的不对的地方,还请各位多多指教!