C# 中开启线程的方法
1、通过委托 只有参数没有返回值的 使用Action委托 有返回值的使用Func当委托 所有的委托都有BeginInvoke方法(最后两个参数是固定的 ) 倒数第一个参数用来给回调函数传递数据 倒数第二个参数是回调函数
using System; using System.Collections.Generic; using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Threading; using System.Threading.Tasks; namespace _016_线程_委托方式发起线程 { class Program { //一般我们会为比较耗时的操作 开启单独的线程去执行,比如下载操作 static int Test(int i,string str) { Console.WriteLine("test"+i+str); Thread.Sleep(100);//让当亲线程休眠(暂停线程的执行) 单位ms return 100; } static void Main(string[] args) {//在main线程中执行 一个线程里面语句的执行 是从上到下的 //1,通过委托 开启一个线程 //Func<int,string,int> a = Test; //IAsyncResult ar = a.BeginInvoke(100,"siki",null,null);// 开启一个新的线程去执行 a所引用的方法 //IAsyncResult 可以取得当前线程的状态 //可以认为线程是同时执行的(异步执行) //Console.WriteLine("main"); //while (ar.IsCompleted==false)//如果当前线程没有执行完毕 //{ // Console.Write("."); // Thread.Sleep(10); //控制子线程的检测频率 //} //int res =a.EndInvoke(ar);//取得异步线程的返回值 //Console.WriteLine(res); //检测线程结束 //bool isEnd = ar.AsyncWaitHandle.WaitOne(1000);//1000毫秒表示超时时间,如果等待了1000毫秒 线程还没有结束的话 那么这个方法会返回false 如果在1000毫秒以内线程结束了,那么这个方法会返回true //if (isEnd) //{ // int res = a.EndInvoke(ar); // Console.WriteLine(res); //} //通过回调 检测线程结束 Func<int, string, int> a = Test; //倒数第二个参数是一个委托类型的参数,表示回调函数,就是当线程结束的时候会调用这个委托指向的方法 倒数第一个参数用来给回调函数传递数据 //IAsyncResult ar = a.BeginInvoke(100, "siki", OnCallBack, a);// 开启一个新的线程去执行 a所引用的方法 a.BeginInvoke(100, "siki", ar => { int res = a.EndInvoke(ar); Console.WriteLine(res+"在lambda表达式中取得"); }, null); Console.ReadKey(); }
// 注意:上述Lambda表达式 直接就可以访问到a 所以最后一个参数不用传 // ar.AsyncState 就是 BeginInvoke(100, "siki", OnCallBack, a)的最后一个参数a static void OnCallBack( IAsyncResult ar ) { Func<int, string, int> a = ar.AsyncState as Func<int, string, int>; int res = a.EndInvoke(ar); Console.WriteLine(res+"在回调函数中取得结果"); } } }
2、通过Thread
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace _017_线程_通过Thread发起线程 { class Program { static void DownloadFile(object filename) // 参数类型必须是 object类型 传递是通过 Start方法 { Console.WriteLine("开始下载:" +Thread.CurrentThread.ManagedThreadId +filename); Thread.Sleep(2000); Console.WriteLine("下载完成"); } static void Main(string[] args) { //Thread t = new Thread(DownloadFile);//创建出来Thread对象,这个线程并没有启动 //t.Start();//开始,开始去执行线程 //Console.WriteLine("Main"); //Thread t = new Thread(() => //{ // Console.WriteLine("开始下载:" + Thread.CurrentThread.ManagedThreadId); // Thread.Sleep(2000); // Console.WriteLine("下载完成"); //}); //t.Start(); //Thread t = new Thread(DownloadFile);//创建出来Thread对象,这个线程并没有启动 //t.Start("xxx.种子");//开始,开始去执行线程 //Console.WriteLine("Main"); //MyThread my = new MyThread("xxx.bt","http://www.xxx.bbs"); //Thread t = new Thread(my.DownFile);//我们构造一个thread对象的时候,可以传递一个静态方法,也可以传递一个对象的普通方法 //t.Start(); //Thread t = new Thread(DownloadFile);//这个是前台线程 Thread t = new Thread(DownloadFile);//这个是前台线程 //t.IsBackground = true;//设置为后台线程 只要前台线程沙雕后 后台都会被强制沙雕 t.Start("xx"); //t.Abort();//终止这个线程的执行 t.Join();//让当前线程睡眠,等待t线程执行完,然后继续运行下面的代码 // } } }
浙公网安备 33010602011771号