C#支持经过多线程并行地执行代码,一个线程有它独立的执行路径,可以与其它的线程同时地运行。一个C#程序开始于一个单线程,这个单线程是被CLR和操做系统(也称为“主线程”)自动建立的,并具备多线程建立额外的线程。
除非被指定,不然全部的例子都假定如下命名空间被引用了:git
using System; using System.Threading;
C#开启线程的方法有:github
总的来讲其实线程的开启基本都涉及到委托的使用。c#
首先来看一个比较简单的例子,采用第一种开启线程的方法——异步委托多线程
using System; using System.Threading; namespace Study { class Program { static void test() { Console.WriteLine("TestThread"); } static void Main(string[] args) { Action a = test; a.BeginInvoke(null, null); Console.WriteLine("MainThread"); Console.ReadLine(); } } }
编译运行,发现结果与预期有所不一样。结果以下图
若是按着逐行运行代码的方式,那么应该是先输出TestThread,可是结果倒是先输出MainThread。
将a.BeginInvoke(null,null);
和Console.WriteLine("MainThread");
对调位置以后,结果和以前的依然一致。这就说明,异步委托开启的线程是和主线程同时同步进行的。
Action委托是指向一个没有返回值的函数,那么假设一个线程,咱们须要取得他的返回结果并输出,那么就要用到Func委托。
看下面的源码异步
using System; using System.Threading; namespace SummerStudy { class Program { static string test(int i, string str) { Console.WriteLine("TestThread" + "\t参数i是:" + i); return str; } static void Main(string[] args) { Func<int, string, string> a = test; IAsyncResult res = a.BeginInvoke(1, "返回值", null, null); string o = a.EndInvoke(res); Console.WriteLine("MainThread\t" + "线程返回值是:" + o); Console.ReadLine(); } }
同时异步委托开启线程中,判断线程是否结束的方法也有两种,一种是利用IAsyncResult的IsCompleted方法,一种是使用方法进行线程结束判断。
具体使用方法以下。函数
IAsyncResult ia = a.BeginInvoke() if(ia.IsCompleted == false) { //GoOn }
IAsyncResult ia = a.BeginInvoke() ia.AsyncWaitHandle.WaitOne(Time);//Time为等待时间,超时后才会运行下一行代码,未完成直接跳出返回false
或者经过自定义方法,BeginInvoke中倒数第二个参数是一个委托,传递一个函数,在线程结束以后会自动的调用。spa
static string Test(int a) { } Func<int, string> a = Test; IAsyncResult ia = a.BeginInvoke(100, CallBack, a); static void CallBack(IAsyncResult ar) { Func<int, string> a = ia.AsyncState as Func<int, string>; string res = a.EndInvoke(ar); }
在使用Lambda表达式做为委托的时候,最后一个参数能够为空,由于Lambda表达式能够访问外部变量。操作系统
使用Thread类建立一个实例,它的构造方法中须要传递一个委托。经过委托绑定线程。
直接上代码线程
using System; using System.Threading; namespace Study { class Program { static void test() { Console.WriteLine("Thread"); Thread.Sleep(2000); Console.WriteLine("TimeOver"); } static void Main(string[] args) { Thread t = new Thread(test); t.Start(); Console.WriteLine("Main"); Console.Read(); } } }
对于须要传递参数的委托,则必须制定参数类型为object,在线程Start方法中传递参数code
namespace SummerStudy { class Program { static void test(object c) { int id = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("Thread,\t线程id为" + id + ",\t参数是:" + c); Thread.Sleep(2000); Console.WriteLine("TimeOver"); } static void Main(string[] args) { Thread t = new Thread(test); t.Start("xxx.avi"); Console.WriteLine("Main"); Console.Read(); } } }
固然你也能够自定义一个类,在类中自定义数据传递。
这种方法有助于节省时间,具体使用方法以下
using System; using System.Threading; namespace SummerStudy { class Program { static void test(object c) { int id = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("Thread,\t线程id为" + id + ",\t参数是:" + c); Thread.Sleep(2000); Console.WriteLine("TimeOver"); } static void Main(string[] args) { ThreadPool.QueueUserWorkItem(test, "asfasf"); Console.Read(); } } }
其中委托必需要有一个参数,不管是否使用该参数。且只适用于使用时间短的线程,不能改变优先级
使用Task类开启线程,还有TaskFactory建立
Task类实例
using System; using System.Threading; using System.Threading.Tasks; namespace SummerStudy { class Program { static void test(object c) { int id = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("Thread,\t线程id为" + id); Thread.Sleep(2000); Console.WriteLine("TimeOver"); } static void Main(string[] args) { Task t = new Task(test, "Asfgasg"); t.Start(); //或者 TaskFactory tf = new TaskFactory(); Task t1 = tf.StartNew(test); Console.Read(); } } }
个人掘金:WarrenRyan
个人简书:WarrenRyan
欢迎关注个人博客得到第一时间更新 https://blog.tity.xyz
个人Github:WarrenRyan
个人博客园:WarrenRyan