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