开启线程的几种方式

目录

线程开启方式(一)-异步委托 

线程开启方式(二)-Thread类

线程开启方式(三)-线程池  

线程开启方式(四)-任务


线程开启方式(一)-异步委托 

        创建线程的一种简单方式是定义一个委托,并异步调用它。 委托是方法的类型安全的引用。Delegate类 还支持异步地调用方法。在后台,Delegate类会创建一个执行任务的线程。

    class Program
    {
        static int Test(int i, string str)
        {
            Console.WriteLine("test" + i + str);
            Thread.Sleep(100);//让当前线程休眠(暂停线程的执行) 单位ms
            return 200;
        }
        static void Main(string[] args)
        {
            //在main线程中执行 一个线程里面语句的执行 是从上到下的
            //1,通过委托 开启一个线程
            Func<int, string, int> a = Test;
            IAsyncResult ar = a.BeginInvoke(30, "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);

            Console .ReadKey ();
        }
    }

线程开启方式(二)-Thread类

        我们构造一个thread对象的时候,可以传递一个静态方法,也可以传递一个对象的普通方法。

        使用Thread类可以创建和控制线程。Thread构造函数的参数是一个无参无返回值的委托类型。

       在这里哪个先输出是无法保证了线程的执行有操作系统决定,只能知道Main线程和分支线程是同步执行的。在这里给Thread传递一个方法,调用Thread的Start方法,就会开启一个线程去执行,传递的方法。

       给线程传递一些数据可以采用两种方式,一种方式是使用带ParameterizedThreadStart委托参数的Thread构造函数,一种方式是创建一个自定义的类,把线程的方法定义为实例方法,这样就可以初始化实例的数据,之后启动线程。

1)传递静态方法

    class Program
    {
        static void DownloadFile()
        {
            Console.WriteLine("开始下载:"+Thread .CurrentThread .ManagedThreadId );
            //Thread .CurrentThread .ManagedThreadId 当前线程id
            Thread.Sleep(2000);
            Console.WriteLine("下载完成");

        }
        static void Main(string[] args)
        {
            Thread t = new Thread(DownloadFile);//创建出来Thread对象,这个线程并没有启动
            t.Start();//开始,开始去执行线程
            Console.WriteLine("Main");
            Console.ReadKey();
        }
    }

   还可以传递参数,方式1:

    class Program
    {
        static void DownloadFile(object fileName)
        {
            Console.WriteLine("开始下载:" +fileName );
            Thread.Sleep(2000);
            Console.WriteLine("下载完成");

        }
        static void Main(string[] args)
        {
            Thread t = new Thread(DownloadFile);//创建出来Thread对象,这个线程并没有启动
            t.Start("种子");//开始去执行线程 
            Console.WriteLine("下载中...");
            Console.ReadKey();
        }
    }

2)传递一个对象的普通方法

    class MyThread
    {
        private string filename;
        private string filepath;

        public MyThread(string fileName, string filePath)
        {
            this.filename = fileName;
            this.filepath = filePath;
        }

        public void DownFile()
        {
            Console.WriteLine("开始下载" + filename + filepath);
            Thread.Sleep(2000);
            Console.WriteLine("下载完成");
        }
    }
    class Program
    {
        static void DownloadFile(object fileName)
        {
            Console.WriteLine("开始下载:" +fileName );
            Thread.Sleep(2000);
            Console.WriteLine("下载完成");

        }
        static void Main(string[] args)
        {
            MyThread my = new MyThread("种子", "http://www.xxx.bbs");
            Thread t = new Thread(my.DownFile);
            t.Start();

            Console.ReadKey();
        }
    }

3)通过lambda表达式(委托参数的地方都可以使用Lambda表达式

    class Program
    {
        static void Main(string[] args)
        {
            //Thread t = new Thread(DownloadFile);//创建出来Thread对象,这个线程并没有启动
            Thread t = new Thread(() =>
            {
                Console.WriteLine("开始下载:" + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(2000);
                Console.WriteLine("下载完成");
            });
            t.Start();//开始,开始去执行线程
            Console.WriteLine("Main");
            Console.ReadKey();
        }
    }

线程开启方式(三)-线程池  

        创建线程需要时间。 如果有不同的小任务要完成,就可以事先创建许多线程 , 在应完成这些任务时发出请求。 这个线程数最好在需要更多的线程时增加,在需要释放资源时减少。

        不需要 自己创建线程池,系统已经有一个ThreadPool类管理线程。 这个类会在需要时增减池中线程的线程数,直到达到最大的线程数。 池中的最大线程数是可配置的。 在双核 CPU中 ,默认设置为1023个工作线程和 1000个 I/o线程。也可以指定在创建线程池时应立即启动的最小线程数,以及线程池中可用的最大线程数。 如果有更多的作业要处理,线程池中线程的个数也到了极限,最新的作业就要排队,且必须等待线程完成其任务。

    class Program
    {
        static void DownloadFile(object fileName)
        {
            Console.WriteLine("线程开始:"+Thread .CurrentThread .ManagedThreadId  );
            Thread.Sleep(2000);
            Console.WriteLine("线程结束");

        }
        static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(DownloadFile);
            ThreadPool.QueueUserWorkItem(DownloadFile);
            ThreadPool.QueueUserWorkItem(DownloadFile);
            ThreadPool.QueueUserWorkItem(DownloadFile);
            ThreadPool.QueueUserWorkItem(DownloadFile);

            Console.ReadKey();
        }
    }

线程开启方式(四)-任务

    class Program
    {
        static void ThreadMethod()
        {
            Console.WriteLine("任务开始:");
            Thread.Sleep(2000);
            Console.WriteLine("任务结束");

        }
        static void Main(string[] args)
        {
            //Task t = new Task(ThreadMethod);
            //t.Start();也可以

            TaskFactory tf = new TaskFactory();
            tf.StartNew(ThreadMethod);

            Console.WriteLine("main");
            Console.ReadKey();
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_40323256/article/details/83146693