多线程笔记
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程笔记相关的知识,希望对你有一定的参考价值。
ParameterizedThreadStart和ThreadStart很像,主要区别是ParameterizedThreadStart委托是带参数的方法,参数值可以是值对像,也可以是自定义对像。
Thread.Start()启动的线程默认为前台线程。系统会待所有前台线程运行结束,应用程序域才会自动卸载。
public class PersonInfo{ public string name{get;set;} public int age{get;set;} public string address{get;set;} } static void ShowMessage(object obj){ PersonInfo pinfo =obj as PersonInfo; Console.WriteLine("name:"+pinfo.name); Console.WriteLine("age:"+pinfo.age); Console.WriteLine("address:"+pinfo.address); }
Thread thread=new Thread(new ParameterizedThreadStart(ShowMessage)); PersonInfo pinfo=new PersonInfo(); pinfo.name="zjh"; pinfo.age="33"; pinfo.address="zhe jiang" thread.Start(pinfo);
线程终止:可以用Abort()方法,执行后会引发一个异常ThreadAbortException.若要想终止线程前恢复线程,可以在捕捉异常后try{}catch(ThreadAbortException ex){ thread.ResetAbort();}调用ResetAbort()方法恢复。使用thread.Join()可以保证应用程序域等待线程结束后才终止运行。
线程池:ThradPool.GetMax(out int workThreads,out int completionPortThreads )和ThreadPool.SetMax(int workThreads,int completionPortThreads )两个方法读取和设置CLR线程池中工作者线程和I/O线程的最大线程数.获取线程池中正在工作的线程数可以使用方法ThreadPool.GetAvailableThreads(out int workThreads,out int completionPortThreads ).工程者线程有两种运行方式:1、使用ThreadPool.QueueUserWorkItem()方法,2、使用委托。
ThreadPool有两个方法可以直接启动工作线程:ThreadPool.QueueUserWorkItem(WaitCallBack),ThreadPool.QueueUserWorkItem(WaitCallBack,object),WaitCallBack指向一个object参数的无返回值方法。
static void AsyncCallBack(object obj){ Thread.Sleep(1000) Console.WriteLine("obj:"+obj); } ThreadPool.QueueUserWorkItem(new WaitCallBack(AsyncCallBack)); ThreadPool.QueueUserWorkItem(new WaitCallBack(AsyncCallBack),"test");
委托类:CRL线程池中的线程,最灵活的最常用的方法就是使用委托的异步方法。
delegate void mydelegate(string a); public void ShowMessage(string a){Console.WriteLine(a);} mydelegate delegate1=new mydelegate(ShowMessage); deletage1("test"); var methods=delegate1.GetType().GetMethods(); if(methods!=null) { foreach(MethodInfo item in methods) { Console.WriteLine("methodname:"+item.Name"); } }
public class MyDelegate:MulticastDelegate { public MyDelegate(object target, int methodPtr); //调用委托方法 public virtual void Invoke(); //异步委托 public virtual IAsyncResult BeginInvoke(AsyncCallback callback,object state); public virtual void EndInvoke(IAsyncResult result); }
调用Invoke()方法,对应此委托的所有方法都会执行。BeginInvoke和EndInvoke则支持委托方法的异步调用,BeginInvoke启用的线程都属性CRL线程池中的工作线程。
IAsynceResult BeginInvoke("test",AsyncCallback callback,object state),除了最后两个参数,其它参数都是委托方法的参数,返回一个IAsyncResult接口的对像,之后调用EndInvoke(iasyncResult)方法,就可以结束异步操作,获取委托的结果。
IAsyncResult
public interface IAsyncResult { object AsyncState {get;} //获取用户定义的对象,它限定或包含关于异步操作的信息。 WailHandle AsyncWaitHandle {get;} //获取用于等待异步操作完成的 WaitHandle。 bool CompletedSynchronously {get;} //获取异步操作是否同步完成的指示。 bool IsCompleted {get;} //获取异步操作是否已完成的指示。 }
判断拖托是否完成可以使用
while(!result。IsCompleted) { //执行主线程程序。 } string result=EndInvoke(result); //如果委托未执行结束,等待200毫秒 while(!result.AsyncWaitHandle.WaitOne(200)){ //执行主线程程序。 } //如果有多个委托,可以使用WaitHandle,它有两个方法:WaitAny(waitHandler[],int),WainAll(waitHandler[],int); mydelegate d1=new mydelegate(ShowMessage)
mydelegate d2=new mydelegate(ShowMessage)
IAsyncResult result1= d1.BeginInvoke("test",null,null);
IAsyncResult result2= d2.BeginInvoke("test1",null,null);
WaitHandle[] waits=new WaitHandle[]{result1.AsyncWaitHandle,result2.AsyncWaitHandle} ;
while(!WaitHandle.WaitAll(waits,200){ //执行主线程程序。 }
使用轮询方式检测异步方法是否完成非常麻烦,而且效率不高,有见于此,可以使用异步方法的回调函数解决。
delegate string mydelegate(string item); static void Complated(IAsyncResult result){ string obj = result.AsyncState.ToString();// AsyncResult result2 = result as AsyncResult ; mydelegate delegate1 = result2.AsyncDelegate; string data=delegate1.EndInvoke(result2) } static string TestDelegate(string item){ return DateTime.Now.Tostring("yyyy-MM-dd")+item; } mydelegate delegate1=new mydelegate(TestDelegate); delegate1.BeginInvoke(delegate1,Complated,"test");
以上是关于多线程笔记的主要内容,如果未能解决你的问题,请参考以下文章