C# 多线程并发编程资料汇总学习

来源:互联网 发布:黄品源 知乎 编辑:程序博客网 时间:2024/05/16 11:50

多线程编程,异步编程,都是感觉非常高大上的技术,在学习了无数前辈们的教学贴后,感觉还是无法融汇贯通,所以决定写个汇总,整理了一下前辈们的代码,为了加强一遍理解。这里一大堆复杂繁琐和啰里啰嗦的饶舌语法就不在重复了,直接上代码。

class Program{    static void Main(string[] args)    {        #region 通过Thread显示当前线程信息        Thread thread0 = Thread.CurrentThread;        thread0.Name = "Main Thread";        string threadMessage = string.Format("Thread ID:{0}\n Current AppDomainId:{1}\n "     +"Current ContextId:{2}\n Thread Name:{3}\n" +"Thread State:{4}\n Thread Priority:{5}\n",thread0.ManagedThreadId, Thread.GetDomainID(),Thread.CurrentContext.ContextID,    thread0.Name, thread0.ThreadState, thread0.Priority);        Console.WriteLine(threadMessage);        #endregion        #region 使用ThreadStart委托        Console.WriteLine("Main threadId is:" + Thread.CurrentThread.ManagedThreadId);        Thread thread1 = new Thread(new ThreadStart(ShowMessage));        thread1.Start();        Console.WriteLine("Do something ..........!");        Console.WriteLine("Main thread working is complete!");        #endregion        #region 使用ParameterizedThreadStart委托        Console.WriteLine("Main threadId is:" + Thread.CurrentThread.ManagedThreadId);        //绑定带参数的异步方法        Thread thread2 = new Thread(new ParameterizedThreadStart(ShowMessage));        Person person = new Person();        person.Name = "Jack";        person.Age = 21;        thread2.Start(person);  //启动异步线程         Console.WriteLine("Do something ..........!");        Console.WriteLine("Main thread working is complete!");        #endregion        #region 前台线程与后台线程        /*        使用Thread.Start()启动的线程默认为前台线程,而系统必须等待所有前台线程运行结束后,        应用程序域才会自动卸载。线程Thread有一个属性IsBackground,通过把此属性设置为true,        就可以把线程设置为后台线程!这时应用程序域将在主线程完成时就被卸载,而不会等待异步线程的运行。        */        Thread thread3 = new Thread(new ThreadStart(ShowMessage));        thread3.IsBackground = true;        thread3.Start();        #endregion        #region 终止线程        Thread thread4 = new Thread(new ThreadStart(AsyncThread));        thread4.IsBackground = true;        thread4.Start();        thread4.Join();        #endregion        /*        CLR线程池分为工作者线程(workerThreads)与I/O线程 (completionPortThreads) 两种,        工作者线程是主要用作管理CLR内部对象的运作,I/O(Input/Output) 线程顾名思义是用于与        外部系统交换信息。通过***ThreadPool.GetMax(out int workerThreads,out int     completionPortThreads )和 ThreadPool.SetMax( int workerThreads, int completionPortThreads)两个方法可以分别读取和设置CLR线程池中工作者线程与I/O线程的最大线程数。        在Framework2.0中最大线程默认为25*CPU数,在Framewok3.0、4.0中最大线程数默认为250*CPU数,        在近年 I3,I5,I7 CPU出现后,线程池的最大值一般默认为1000、2000。        若想测试线程池中有多少的线程正在投入使用,        可以通过ThreadPool.GetAvailableThreads( out int workerThreads,out int completionPortThreads ) 方法。 使用CLR线程池的工作者线程一般有两种方式,一是直接通过 ThreadPool.QueueUserWorkItem() 方法,二是通过委托        */        #region 通过QueueUserWorkItem启动工作者线程        //把CLR线程池的最大值设置为1000        ThreadPool.SetMaxThreads(1000, 1000);        //显示主线程启动时线程池信息        ThreadMessage("Start");        //启动工作者线程        ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback1));        ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback2), "Hello Elva");        #endregion        /*        通过委托类实现线程池这种方法是在太恶心了,如果不了解原理生搬硬套,很容易走形式,而且记不住,        甚是麻烦,建议大家好好看看微软的底层框架,为啥微软会将这种方法做的如此难以理解,        我想肯定是微软将此方法封装的太深造成的。        */        #region 利用BeginInvoke与EndInvoke完成异步委托方法        ThreadMessage("Main Thread");        //建立委托        MyDelegate myDelegate0 = new MyDelegate(Hello);        //异步调用委托,获取计算结果        IAsyncResult result0 = myDelegate0.BeginInvoke("Leslie", null, null);        //完成主线程其他工作        Console.WriteLine(".............");        //等待异步方法完成,调用EndInvoke(IAsyncResult)获取运行结果        string data0 = myDelegate0.EndInvoke(result0);        Console.WriteLine(data0);        #endregion        #region 轮询方式        ThreadMessage("Main Thread");        //建立委托        MyDelegate myDelegate1 = new MyDelegate(Hello);        //异步调用委托,获取计算结果        IAsyncResult result1 = myDelegate1.BeginInvoke("Leslie", null, null);        //在异步线程未完成前执行其他工作        while (!result1.IsCompleted)        {            Thread.Sleep(200);            Console.WriteLine("Main thead do work!");        }        while (!result1.AsyncWaitHandle.WaitOne(200))        {            Console.WriteLine("Main thead do work!");        }        string data1 = myDelegate1.EndInvoke(result1);        Console.WriteLine(data1);        #endregion        #region 监视多个运行对象        ThreadMessage("Main Thread");        //建立委托        MyDelegate myDelegate2 = new MyDelegate(Hello);        //异步调用委托,获取计算结果        IAsyncResult result2 = myDelegate2.BeginInvoke("Leslie", null, null);        //此处可加入多个检测对象        WaitHandle[] waitHandleList = new WaitHandle[] { result2.AsyncWaitHandle };        while (!WaitHandle.WaitAll(waitHandleList, 200))        {            Console.WriteLine("Main thead do work!");        }        string data2 = myDelegate2.EndInvoke(result2);        Console.WriteLine(data2);        #endregion        /*           这种回调函数的方式代替了轮询的方式,但更是难以理解,只能机械的跟套公式一样的运用,        那么你跟不会多线程的人没有任何区别。但是如果你理解了底层的框架实现原理,相信就会清晰多了,        我这个小菜暂时只能看看怎么用,惭愧。        */        #region 回调函数        ThreadMessage("Main Thread");        //建立委托        MyDelegate myDelegate3 = new MyDelegate(Hello);        //异步调用委托,获取计算结果        myDelegate3.BeginInvoke("Leslie", new AsyncCallback(Completed), null);        //建立Person对象        Person person3 = new Person();        person3.Name = "Elva";        person3.Age = 27;        //异步调用委托,输入参数对象person, 获取计算结果        myDelegate3.BeginInvoke("Leslie", new AsyncCallback(Completed3), person);        //在启动异步线程后,主线程可以继续工作而不需要等待        for (int n = 0; n < 6; n++)        {            Console.WriteLine("  Main thread do work!");        }        Console.WriteLine("");        #endregion    }    //展示进程信息    public static void ShowMessage()    {        string message = string.Format("Async threadId is :{0}",Thread.CurrentThread.ManagedThreadId);        Console.WriteLine(message);        for (int n = 0; n < 10; n++)        {            Thread.Sleep(300);            Console.WriteLine("The number is:" + n.ToString());        }    }    public class Person    {        public string Name{ get;set;}        public int Age { get;set;}    }    public static void ShowMessage(object person)    {       if (person != null)        {          Person _person = (Person)person;           string message = string.Format("\n{0}'s age is {1}!\nAsync threadId is:{2}",_person.Name, _person.Age, Thread.CurrentThread.ManagedThreadId);           Console.WriteLine(message);        }        for (int n = 0; n < 10; n++)        {            Thread.Sleep(300);            Console.WriteLine("The number is:" + n.ToString());        }    }    //以异步方式调用    static void AsyncThread()    {        try        {            string message = string.Format("\nAsync threadId is:{0}",               Thread.CurrentThread.ManagedThreadId);            Console.WriteLine(message);            for (int n = 0; n < 10; n++)            {                //当n等于4时,终止线程                if (n >= 4)                {                    Thread.CurrentThread.Abort(n);                }                Thread.Sleep(300);                Console.WriteLine("The number is:" + n.ToString());            }        }        catch (ThreadAbortException ex)        {           //输出终止线程时n的值            if (ex.ExceptionState != null)                Console.WriteLine(string.Format("Thread abort when the number is: {0}!", ex.ExceptionState.ToString()));            //取消终止,继续执行线程            Thread.ResetAbort();            Console.WriteLine("Thread ResetAbort!");        }        //线程结束        Console.WriteLine("Thread Close!");    }    static void AsyncCallback1(object state)    {        Thread.Sleep(200);        ThreadMessage("AsyncCallback");        Console.WriteLine("Async thread do work!");    }    static void AsyncCallback2(object state)    {        Thread.Sleep(200);        ThreadMessage("AsyncCallback");        string data = (string)state;        Console.WriteLine("Async thread do work!\n" + data);    }    //显示线程现状    static void ThreadMessage(string data)    {        string message = string.Format("{0}\n  CurrentThreadId is {1}",             data, Thread.CurrentThread.ManagedThreadId);        Console.WriteLine(message);    }    delegate string MyDelegate(string name);    static string Hello(string name)    {        ThreadMessage("Async Thread");        Thread.Sleep(2000);         return "Hello " + name;    }    static void Completed(IAsyncResult result)    {        ThreadMessage("Async Completed");        //获取委托对象,调用EndInvoke方法获取运行结果        AsyncResult _result = (AsyncResult)result;        MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;        string data = myDelegate.EndInvoke(_result);        Console.WriteLine(data);    }    static void Completed3(IAsyncResult result)    {        ThreadMessage("Async Completed");        //获取委托对象,调用EndInvoke方法获取运行结果        AsyncResult _result = (AsyncResult)result;        MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;        string data = myDelegate.EndInvoke(_result);        //获取Person对象        Person person = (Person)result.AsyncState;        string message = person.Name + "'s age is " + person.Age.ToString();        Console.WriteLine(data + "\n" + message);    }   }

这里只是简单的代码整理,如果想看全部教程的同学,可以参考风尘浪子 前辈的博文
链接如下:http://kb.cnblogs.com/page/130487/

0 0
原创粉丝点击