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

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

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/

你可能感兴趣的:(源码分析,基础原理,.Net)