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线程执行完,然后继续运行下面的代码
            //
        }
    }
}

 

posted @ 2021-04-13 21:13  一个新星的诞生  阅读(47)  评论(0)    收藏  举报