您的位置:首页 - 教程 - C# - 正文
C#多线程学习

一、谈进程和线程。

进程:当一个程序被打开运行时,此刻它就是一个进程。它是操作系统进行资源调度和分配的基本单位,一个进程可以有若干个线程,线程也可以同时帮进程做多个事情

线程:线程程序执行流的最小单位,自己不拥有资源,但是他可以与同进程中的其他线程共享进程中所有的资源,一个线程可以创建或者终止其他的线程

多线程:在单CPU系统的单位时间内,CPU只能允许单个线程,顺序取决于线程的级别{从低到高:Lowest、BelowNormal、Normal(默认)、AboveBoral、Highest},只因为相互切换频密且时间非常短暂,所以说为多线程可以视为同时运行。

二、用Thread类创建线程

1、几个经常用到属性:

IsAlive:bool类型,用于判断线程是否被执行,创建线程后不执行该值为False,调用Start()方法运行线程后该值为True,当线程结束后该值为False,其余ThreadState状态都为True

IsBackground:是否为前台线程,用Thread类创建线程(Thread thread=new Thread())默认为前台线程,即IsBackground=False,CLR线程池所建立的线程总是默认为后台线程。当主程序关闭时前台线程不会随主程序的关闭而关闭

ManagedThreadId:获取线程唯一标识符

Name:线程名字

Priority:线程有限级别

ThreadState:线程状态{unstarted、Running、WaitSleepJoin等等}

2、熟悉两个委托:public delagate void ThreadStart()、public delegate void ParameterizedThreadStart(object a)

通过以上应该很清楚的看到这两个委托的使用方法。

3、线程中的一些方法:

Sleep:把正在运行的线程挂起一段时间

Abort:终止本线程

Join:阻塞调用线程,只当这个线程完成后则继续之后的操作或线程

Interrupt:中断处于WautSleepJoin状态的线程

Start:执行本线程

Suppend表示挂起,Resume表示恢复挂起的线程(已不能用,这里不做解释)

三、线程池

ThreadPool线程池中包含了QueueUserWorkItem这个方法用来进行异步调用,可以带Object

的参数,也可以不带,不带参数默认为NULL

ThreadPool.SetMaxThreads()用于设置线程池最大线程数量,有两个参数,第一个设置工作者线程,第一个用于设置IO线程

ThreadPool.QueueUserWorkItem(new WaitCallBack(方法名称),参数)

上面这一步就已经在线程池中创建了一个线程,WaitCallBack同样是一个委托: public delegate void WaitCallback(object state);

通过QueueUserWorkItem的方式来启动线程比较简单,但是不满足我们在实际开发中的需要,它只能最多带一个参数,而且无返回值。

四、使用委托类来开始一个线程

1、委托类几个重要的方法:

Invoke();调用Invoke()方法时,对应此委托的所有方法都会被执行

BeginInvoke(),EndInvoke()支持委托的异步调用,由BeginInvoke启动的线程都属于线程池中的线程‘

2、BeginInvoke参数说明:

倒数第一个参数用于调用外部的数据,相当于网回调函数中传递参数

倒数第二个参数是回调函数

前面参数为匹配委托的方法中的参数

public delegate string GetString(string a)//声明一个委托

static void Main(string[] arg)

{

GetString getstring=new GetString(GetName);//建立一个委托,并为他绑定一个方法

//异步调用委托需要用到IAsyncResult这一个接口

【//这种方式异步调用需要等到异步调用的方法执行完毕后才会调用主线程,不符合实际开发需要

IAsyncResult Result=getstring.BeginInvoke("张三",null,null);

string name=getstring.EndInvoke(Result);//获取方法GetName返回来的值

Console.WriteLine(name);

Console.WriteLine("主线程");

}

 

【//通过IAsyncResult中的成员IsCompleted来获取异步操作是否完成,bool类型,当异步调用操作未完成也会继续执行主线程

IAsyncResult Result=getstring.BeginInvoke("张三",null,null);

while(!Result.IsCompleted)

{

Console.WriteLine("主线程");

}

string name=getstring.EndInvoke(Result);//获取方法GetName返回来的值

Console.WriteLine(name);

 

【//使用WailHandle中的WaitOne()这个方法完成异步调用

IAsyncResult Result=getstring.BeginInvoke("张三",null,null);

while(!Result.AsyncWaitHandle.WaitOne(200))//参数代表时间,以一种轮询的方式去判断异步调用是否完成

{

Console.WriteLine("主线程");

}

string name=getstring.EndInvoke(Result);//获取方法GetName返回来的值

Console.WriteLine(name);

【//如果需要监视多个异步调用是否完成,这个时候我们需要声明一盒WaitHandle的数组,将需要监视的对象传进去

IAsyncResult Result=getstring.BeginInvoke("张三",null,null);

Waithandle[] waitlist=new Waithandle[]{Result.AsyncWaitHandle,.....};

//主要有两个方法进行监视 1、WaitAll(数组,时间),等待所有异步调用完成后返回一个bool值,2、WaitAny

等待waitlist其中一个完成异步调用后即返回一个int类型的值,该值就是数组的索引

while(!WaitHandle.WaitAll(waitlist,200))

{

Console.WriteLine("主线程");

}

 

pubslic string GetName(string name)

{

return "Hi"+name;

}

 

 

 

 

 

 

评论: