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
- C# 多线程并发编程资料汇总学习
- Linux并发编程资料汇总
- Linux并发编程资料汇总
- Linux并发编程资料汇总
- 编程资料 -C# 多线程
- 编程资料 -C# 多线程
- 编程资料 -C# 多线程
- Java多线程并发编程学习
- C# 多线程、异步编程与并发服务器
- Swift编程语言学习资料汇总
- Java 5.0多线程编程学习资料笔录
- Linux下的多线程编程 学习资料
- [学习随笔]并发编程与多线程一
- [学习随笔]并发编程与多线程二
- C# 多线程编程学习笔记
- c# socket 资料汇总
- C#资料下载汇总
- C#编码资料汇总
- Memcached客户端性能评测报告
- Quartz 2D基本介绍
- 异常处理语句
- win10 10074版本qq显示问题
- C++类与对象(3) - 空class&struct的大小
- C# 多线程并发编程资料汇总学习
- 职业选择
- 关于螺旋填数的理解
- 微信WIFI,帮你做好客流量统计
- Quartz 2D基本绘图
- Memcached哈希性能优化(八)——总结报告
- HDU1873---看病要排队
- UI控件基础篇————简易图片浏览器
- 不求人,手把手教你学会微信WIFI!