C# Task 总结

一、概述

https://blog.csdn.net/m0_48667560/article/details/133364455

  1. Task基础介绍 
  2. Task的创建  有四种方式
  3. Task的传入参数
  4. Task获得返回值

*Action 和Func 的区别

Action:

没有参数同时没有返回值

Func委托:

Func有返回值 有参数,但是参数最多是16个

-------------------Func  没有返回值类型的委托------------------------------
Func至少0个输入参数,至多16个输入参数,根据返回值泛型返回。必须有返回值,不可void。

Func<int> 表示没有输入参参,返回值为int类型的委托。

Func<object, string, int> 表示传入参数为object, string ,返回值为int类型的委托。

Func<object, string, int> 表示传入参数为object, string, 返回值为int类型的委托。

Func < T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型),返回值为int类型的委托。

Task 的优点

  • 在任务启动后,可以随时以任务延续的形式注册回调。
  • 通过使用 ContinueWhenAll 和 ContinueWhenAny 方法或者 WaitAll 方法或 WaitAny 方法,协调多个为了响应 Begin_ 方法而执行的操作。
  • 在同一 Task 对象中封装异步 I/O 绑定和计算绑定操作。
  • 监视 Task 对象的状态。
  • 使用 TaskCompletionSource 将操作的状态封送到 Task 对象。

二、Task 的创建

public Task(Action action);
public Task(Action<object> action, object state);
public Task(Action action, CancellationToken cancellationToken);
public Task(Action action, TaskCreationOptions creationOptions);
public Task(Action<object> action, object state, CancellationToken cancellationToken);
public Task(Action<object> action, object state, TaskCreationOptions creationOptions);
public Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions);
public Task(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions);

task的建立有四种方式

1、使用委托和方法

 // 第一种方法 使用委托和方法
            Task task = new Task(new Action(PringtMsg));

2、 使用匿名委托

 // 使用匿名委托
            Task taskdelegate = new Task(delegate {

                Console.WriteLine("hello world    taskdelegate");

            });

3、使用lamdba 匿名委托

// 第三种方式  使用lamdba和匿名方式
            Task task_lamdba= new Task(() =>
            {
                Console.WriteLine("hello world    task_lamdba"); 


            });

4、使用lamdba+方法委托

  //第二种 使用lamdba 表达式的方法
            Task lamdba = new Task(() => PringtMsg2());

测试代码:

 static void Main()
        {
         

            //----------------------------------------------------------创建------------------------------------------------------------------
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);


            // 第一种方法 使用委托和方法
            Task task = new Task(new Action(PringtMsg));

            // 使用匿名委托
            Task taskdelegate = new Task(delegate {

                Console.WriteLine("hello world    taskdelegate");

            });

            //第二种 使用lamdba 表达式的方法
            Task lamdba = new Task(() => PringtMsg2());


            // 第三种方式  使用lamdba和匿名方式
            Task task_lamdba= new Task(() =>
            {
                Console.WriteLine("hello world    task_lamdba"); 


            });
            task.Start();
            taskdelegate.Start();
            lamdba.Start();
            task_lamdba.Start();
            Application.Run(new Form1());

            Console.Read();
        }

        private static void PringtMsg()
        {
            Console.WriteLine("hello world");
        }

        private static void PringtMsg2()
        {
            Console.WriteLine("hello world2222 ");
        }
    }

 三、Task 中传入参数

在创建task 的时候我们在构造函数中传入一个System.Action,想向Task传入参素,只能用System.Action<object>


            string[] messages = { "First task", "Second task", "Third task", "Fourth task" };
     
            foreach (var item in messages)
            {
                Task taskm = new Task((s)=>Print((string)s),item);


                // 第二种方式
                Task t1 = new Task(()=> Print222(item));
                taskm.Start();
                t1.Start();
            }

 private static void Print(string msg)
        {
            Console.WriteLine($"print message : {msg}");
        }


        private static void Print222(string msg)
        {
            Console.WriteLine($"print Print222 : {msg}");
        }

四、Task 有返回值

task.result 在获取结果的时候会阻塞线程,等到获取结果之后才会执行后面的程序代码

//=============================================Task 返回值=====================================================================
            Task<int> sum = new Task<int>(()=>GetSum());
            sum.Start();
            Console.WriteLine($"task result is {sum.Result}");
            //============================================= Task 返回值 =====================================================================




 private static int GetSum()
        {
            int sum = 0;
            for (int i = 0; i < 10; i++)
            {
                sum = sum + i;
                Thread.Sleep(100);
            }
            return sum;
        }

传入参数 输出结果

   =============================================传入参数   Task 返回值=====================================================================
            Task<double> ta = new Task<double>((i)=>GetNum((int)i),100);
            ta.Start();
            Console.WriteLine($"ta result is {ta.Result}");
            =============================================传入参数   Task 返回值=====================================================================



            Console.Read();


        private static double GetNum(int len)
        {
            double sum = 0;
            for (int i = 0; i <= len; i++)
            {
                sum = sum + i;
                Thread.Sleep(10);
            }
            return sum;
        }


            //-----------------------------------------------------Action  没有返回值类型的委托------------------------------------------------------------------
            Func func = fun1;
            Task.Factory.StartNew(new Action(func));  // 没有参数




            //-----------------------------------------------------Func  没有返回值类型的委托------------------------------------------------------------------
            //Func至少0个输入参数,至多16个输入参数,根据返回值泛型返回。必须有返回值,不可void。

            //Func<int> 表示没有输入参参,返回值为int类型的委托。

            //Func<object, string, int> 表示传入参数为object, string ,返回值为int类型的委托。

            //Func<object, string, int> 表示传入参数为object, string, 返回值为int类型的委托。

            //Func < T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型),返回值为int类型的委托。

            // 没有参数
            Func func78787 = delegate ()
              {
                  Console.WriteLine("func78787---------");
              };
            Task.Run(()=> { func78787(); });



            //   只有一个参数
            // action<object>
            {
                Task.Factory.StartNew(fun2, " 只有一个参数    9999999999999999999999");
                Task.Run(() => { fun2(" 只有一个参数  88888888888888888888888888  "); });

            }


            // func 方法  一个参数  有返回值类型的委托
            var s = Task<int>.Factory.StartNew(new Func<object, int>(F4),20);
            Console.WriteLine(s.Result);


            //func委托 返回值
            // 在Task 中只显示返回值  
            //有两个参数  并且有返回值
            var niuni=Task<bool>.Factory.StartNew(new Func<bool>(() => FunWithMultiPara(20, "2")));
            Console.WriteLine(niuni.Result);

Task.Factory.StartNew<TResualt>

            // ========================================================================================================================
            Task<int> factory_tesk = Task.Factory.StartNew<int>((n) => 
            {
                // 这里的M变量名是不能和上面的重复的
                int M = 0;
                for (int i = 0; i <= (int)n; i++)
                {
                    M = M + i;
                }
                return M;
            }, 100);

            Console.WriteLine($"sum = {factory_tesk.Result}");

五、Wait

Wait() 

Wait() 等待执行调用任务完成,然后执行下一步; 即阻塞了主线程

   static void Main()
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
            var t1 = Task.Run(() =>
            {
                Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(10000);
            });
            t1.Wait();

            var t2 = Task.Run(() =>
            {
                Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(5000);
            });
            t2.Wait();
            var t3 = Task.Run(() =>
            {
                Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(500);
            });
            t3.Wait();
            //t3.ContinueWith(t=> {

            //    Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
            //    Thread.Sleep(5000);
            //});
         

            var t4 = Task.Run(() =>
            {
                Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(2);
            });
            t4.Wait();

            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
            Console.ReadLine();

        }

ContinueWith()

  static void Main()
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
            var t1 = Task.Run(() =>
            {
                Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(10000);
            });


            var t2 = Task.Run(() =>
            {
                Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(5000);
            });

            var t3 = Task.Run(() =>
            {
                Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(500);
            });
            t3.ContinueWith(t=> {

                Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(5000);
            });


            var t4 = Task.Run(() =>
            {
                Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(2);
            });

            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
            Console.ReadLine();

        }

Task.WaitAll

task.WaitAll等到所有任务都完成之后,才进行主线程的下一步操作,即阻塞主线程

 static void Main()
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
            var t1 = Task.Run(() =>
            {
                Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(10000);
            });
            //t1.Wait();

            var t2 = Task.Run(() =>
            {
                Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(5000);
            });
          //  t2.Wait();
            var t3 = Task.Run(() =>
            {
                Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(500);
            });
           // t3.Wait();
            //t3.ContinueWith(t=> {

            //    Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
            //    Thread.Sleep(5000);
            //});
         

            var t4 = Task.Run(() =>
            {
                Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(2);
            });
            //  t4.Wait();

            List<Task> allTask = new List<Task> {t1,t2,t3,t4 };
            Task.WaitAll(allTask.ToArray());

            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
            Console.ReadLine();

        }

静态方法Task.WaitAny

任意一个完成就执行下面的代码

    static void Main()
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
            var t1 = Task.Run(() =>
            {
                Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(10000);
            });
            //t1.Wait();

            var t2 = Task.Run(() =>
            {
                Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(5000);
            });
          //  t2.Wait();
            var t3 = Task.Run(() =>
            {
                Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(500);
            });
           // t3.Wait();
            //t3.ContinueWith(t=> {

            //    Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
            //    Thread.Sleep(5000);
            //});
         

            var t4 = Task.Run(() =>
            {
                Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(2);
            });
            //  t4.Wait();

            List<Task> allTask = new List<Task> {t1,t2,t3,t4 };
            //Task.WaitAll(allTask.ToArray());
            Task.WaitAny(allTask.ToArray());

            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
            Console.ReadLine();

        }

任务工厂Task.Factory.ContinueWhenAll

当ContinueWhenAll中所有任务都完成时执行回调方法不阻塞主线程

    static void Main()
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
            var t1 = Task.Run(() =>
            {
                Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(10000);
            });
            //t1.Wait();

            var t2 = Task.Run(() =>
            {
                Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(5000);
            });
          //  t2.Wait();
            var t3 = Task.Run(() =>
            {
                Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(500);
            });
           // t3.Wait();
            //t3.ContinueWith(t=> {

            //    Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
            //    Thread.Sleep(5000);
            //});
         

            var t4 = Task.Run(() =>
            {
                Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(2);
            });
            //  t4.Wait();

            List<Task> allTask = new List<Task> {t1,t2,t3,t4 };
            //Task.WaitAll(allTask.ToArray());
            //Task.WaitAny(allTask.ToArray());

            Task.Factory.ContinueWhenAll(allTask.ToArray(),task=> 
            {
                Console.WriteLine("所有子线程都已经完成了");
            });

            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
            Console.ReadLine();

        }

Thread.Sleep与Task.Delay的区别

 Thread.Sleep在延期时间内会阻塞主线程,例如: Thread.Sleep(5000),在UI界面中会卡顿界面5秒,界面无法执行其他操作,原因是Thread属性IsBackground默认为前台线程,

Task.Delay(5000)延时期间不会阻塞主线程

六、线程同步

线程不安全:多线程同时修改一个变量;或者一个线程修改,一个线程读取,则可能出现BUG

线程同步的方法有:Mutex、Monitor、lock

lock

  static string str= "abcd";
       static int Tnum = 10;
       static  void  BuyTickets()
        {
            while (true)
            {

                lock(str)
                {
                    if (Tnum>0)
                    {
                        Thread.Sleep(1000);
                        Console.WriteLine(Thread.CurrentThread.Name+"    ----   票数  "+Tnum--);
                    }
                }

            }
        }



        static  void Main()
        {

            Thread ta = new Thread(BuyTickets);
            ta.Name = "线程 一";
            Thread tb = new Thread(BuyTickets);
            tb.Name = "线程 二";
            Thread tc = new Thread(BuyTickets);
            tc.Name = "线程 三";
            Thread td = new Thread(BuyTickets);
            td.Name = "线程 四";

            ta.Start();
            tb.Start();
            tc.Start();
            td.Start();

            Console.ReadLine();

        }

七、线程异步

理解异步函数async和await的用法_async await用法-CSDN博客

理解异步函数async和await的用法_async await用法-CSDN博客

async 是异步的意思

表示是一个异步的函数,而await 也只能在这个函数中使用,不能单独使用,其返回值是一个Promise对象,如果 Promise的状态变成了 resolve 或者 rejcet,那么 async函数会恢复执行。并会阻塞该函数内后面的代码

await 可以理解为async await 

await 只能在async 的函数中使用

async 表示一个异步的方法,而await 是用来等待这个方法执行的

async和await

不加async 和await
  static  void timeout()
        {
            Task.Run(()=> {

                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(" -----------  "+i.ToString());
                }
            });



            Task.Run(() => {

                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(" def  " + i.ToString());
                }
            });

        }

        static void Main()
        {
            Console.WriteLine("   开始 ");
            timeout();
            Console.WriteLine("   结束 ");
            Console.ReadLine();

        }

从结果看是无序的

加async和await 

  static async void timeout()
        {
            await Task.Run(()=> {

                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(" -----------  "+i.ToString());
                }
            });



            await Task.Run(() => {

                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(" def  " + i.ToString());
                }
            });

        }

        static void Main()
        {
            Console.WriteLine("   开始 ");
            timeout();
            Console.WriteLine("   结束 ");
            Console.ReadLine();

        }

结果如下:

  static async void AsyncMethond()
        {
            Console.WriteLine("开始异步代码");

            // 异步方法,当使用await 的时候是使用task 的异步任务,否则还是同步执行
            var result = await MyMethod();
            Console.WriteLine("异步代码执行完毕" + result.ToString());
        }

        static  async Task<int> MyMethod()
        {
           for (int i = 0; i < 5; i++)
           {
             Console.WriteLine("异步执行" + i.ToString() + "..");
             await Task.Delay(10); //模拟耗时操作
           }
         return 100;
        }

        /// <summary>
        ///   main 方法不能使用 async 
        /// </summary>
        static void Main()
        {
            Console.WriteLine("主线程测试开始..");
            AsyncMethond();
            Thread.Sleep(20000);
            Console.WriteLine("主线程测试结束..");
            Console.ReadLine();
        }

案例二

在main 函数中是不能使用await 的

   static async void test()
        {
            log("test: await之前");

            await doo();  // await  是等待doo 里面的都执行完之后才能打印下面的log 

            log("test: await之后");


        }

        static async Task doo()
        {

            // await Task 每个上面都是按照顺序输出执行的
            log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 1; }));

            log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 2; }));

            log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 3; }));

            Thread.Sleep(1000);


            Console.WriteLine("doo中在Task外的Thread.Sleep执行完毕");


        }

         static  void log(string msg)
        {
            Console.WriteLine("{0}: {1}", Thread.CurrentThread.ManagedThreadId, msg);
        }




        static void Main()
        {
            Console.WriteLine("   开始 ");
            test();  // test 前面没有await  所以会执行下面 log("Main:调用test后"); 的日值

            log("Main:调用test后");

            Thread.Sleep(Timeout.Infinite);

            Console.ReadLine();

        }


修改:给task 上有int 的返回值

  static async void test()
        {
            log("test: await之前");

         //   await doo();  // await  是等待doo 里面的都执行完之后才能打印下面的log 
            Console.WriteLine("doo结果:{0}", await doo());
            log("test: await之后");


        }

        //static async Task doo()
        //{

        //    // await Task 每个上面都是按照顺序输出执行的
        //    log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 1; }));

        //    log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 2; }));

        //    log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 3; }));

        //    Thread.Sleep(1000);


        //    Console.WriteLine("doo中在Task外的Thread.Sleep执行完毕");


        //}
        static async Task<int> doo()
        {
            // await Task 每个上面都是按照顺序输出执行的
            var v1 = await Task.Run(() => { Thread.Sleep(1000); log("Task  1"); return 1; });
            var v2 = await Task.Run(() => { Thread.Sleep(1000); log("Task  2"); return 2; });
            var v3 = await Task.Run(() => { Thread.Sleep(1000); log("Task  3"); return 3; });

            //不使用 await  线程池线程
            ThreadPool.QueueUserWorkItem(_=> {
                Thread.Sleep(1000);
                Console.WriteLine("ThreadPool.QueueUserWorkItem");
            });

            _ = Task.Run(() =>
              {
                  Thread.Sleep(1000);
                  Console.WriteLine("Task.Run");
              });

            return v1 + v2 + v3;
            Console.WriteLine("doo中在Task外的Thread.Sleep执行完毕");


        }


        static  void log(string msg)
        {
            Console.WriteLine("{0}: {1}", Thread.CurrentThread.ManagedThreadId, msg);
        }




        static void Main()
        {
            Console.WriteLine("   开始 ");
            test();  // test 前面没有await  所以会执行下面 log("Main:调用test后"); 的日值

            log("Main:调用test后");

            Thread.Sleep(Timeout.Infinite);

            Console.ReadLine();

        }

全部代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Threading;
namespace TaskTest
{
    static class Program
    {

        static async void test()
        {
            log("test: await之前");

         //   await doo();  // await  是等待doo 里面的都执行完之后才能打印下面的log 
            Console.WriteLine("doo结果:{0}", await doo());
            log("test: await之后");


        }

        //static async Task doo()
        //{

        //    // await Task 每个上面都是按照顺序输出执行的
        //    log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 1; }));

        //    log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 2; }));

        //    log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 3; }));

        //    Thread.Sleep(1000);


        //    Console.WriteLine("doo中在Task外的Thread.Sleep执行完毕");


        //}
        static async Task<int> doo()
        {
            // await Task 每个上面都是按照顺序输出执行的
            var v1 = await Task.Run(() => { Thread.Sleep(1000); log("Task  1"); return 1; });
            var v2 = await Task.Run(() => { Thread.Sleep(1000); log("Task  2"); return 2; });
            var v3 = await Task.Run(() => { Thread.Sleep(1000); log("Task  3"); return 3; });

            //不使用 await  线程池线程
            ThreadPool.QueueUserWorkItem(_=> {
                Thread.Sleep(1000);
                Console.WriteLine("ThreadPool.QueueUserWorkItem");
            });

            _ = Task.Run(() =>
              {
                  Thread.Sleep(1000);
                  Console.WriteLine("Task.Run");
              });

            return v1 + v2 + v3;
            Console.WriteLine("doo中在Task外的Thread.Sleep执行完毕");


        }


        static  void log(string msg)
        {
            Console.WriteLine("{0}: {1}", Thread.CurrentThread.ManagedThreadId, msg);
        }




        static void Main()
        {
            Console.WriteLine("   开始 ");
            test();  // test 前面没有await  所以会执行下面 log("Main:调用test后"); 的日值

            log("Main:调用test后");

            Thread.Sleep(Timeout.Infinite);

            Console.ReadLine();

        }











        static async void timeout()
        {
            await Task.Run(()=> {

                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(" -----------  "+i.ToString());
                }
            });



            await Task.Run(() => {

                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(" def  " + i.ToString());
                }
            });

        }

        static void Main77()
        {
            Console.WriteLine("   开始 ");
            timeout();
            Console.WriteLine("   结束 ");
            Console.ReadLine();

        }


        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        /// 
        static string str= "abcd";
       static int Tnum = 10;
       static  void  BuyTickets()
        {
            while (true)
            {

                lock(str)
                {
                    if (Tnum>0)
                    {
                        Thread.Sleep(1000);
                        Console.WriteLine(Thread.CurrentThread.Name+"    ----   票数  "+Tnum--);
                    }
                }

            }
        }



        static  void Main66()
        {

            Thread ta = new Thread(BuyTickets);
            ta.Name = "线程 一";
            Thread tb = new Thread(BuyTickets);
            tb.Name = "线程 二";
            Thread tc = new Thread(BuyTickets);
            tc.Name = "线程 三";
            Thread td = new Thread(BuyTickets);
            td.Name = "线程 四";

            ta.Start();
            tb.Start();
            tc.Start();
            td.Start();

            Console.ReadLine();

        }





























        static void Main2()
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
            var t1 = Task.Run(() =>
            {
                Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(10000);
            });
            //t1.Wait();

            var t2 = Task.Run(() =>
            {
                Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(5000);
            });
          //  t2.Wait();
            var t3 = Task.Run(() =>
            {
                Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(500);
            });
           // t3.Wait();
            //t3.ContinueWith(t=> {

            //    Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
            //    Thread.Sleep(5000);
            //});
         

            var t4 = Task.Run(() =>
            {
                Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
                Thread.Sleep(2);
            });
            //  t4.Wait();

            List<Task> allTask = new List<Task> {t1,t2,t3,t4 };
            //Task.WaitAll(allTask.ToArray());
            //Task.WaitAny(allTask.ToArray());

            Task.Factory.ContinueWhenAll(allTask.ToArray(),task=> 
            {
                Console.WriteLine("所有子线程都已经完成了");
            });

            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
            Console.ReadLine();

        }







































        delegate void Func();
        //函数 fun1
        static void fun1()
        {
            Console.WriteLine("没有参数action");
        }
        //函数 fun2
        static void fun2(object s)
        {
            Console.WriteLine(s.ToString());
        }


        public static int F4(object a)
        {
            Console.WriteLine(a);
            return 0;
        }

        static bool FunWithMultiPara(int i, string s)
        {
            return i.ToString().Equals(s) ? true : false;
        }


       static async void AsyncMethond()
        {
            Console.WriteLine("开始异步代码");

            // 异步方法,当使用await 的时候是使用task 的异步任务,否则还是同步执行
            var result = await MyMethod();
            Console.WriteLine("异步代码执行完毕" + result.ToString());
        }

        static  async Task<int> MyMethod()
        {
           for (int i = 0; i < 5; i++)
           {
             Console.WriteLine("异步执行" + i.ToString() + "..");
             await Task.Delay(10); //模拟耗时操作
           }
         return 100;
        }

        /// <summary>
        ///   main 方法不能使用 async 
        /// </summary>
        static void Main3()
        {
            Console.WriteLine("主线程测试开始..");
            AsyncMethond();
            Thread.Sleep(20000);
            Console.WriteLine("主线程测试结束..");
            Console.ReadLine();
        }





        [STAThread]
        static void Main1()
        {
            //----------------------------------------------------------创建------------------------------------------------------------------
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);




            //-----------------------------------------------------Action  没有返回值类型的委托------------------------------------------------------------------
            Func func = fun1;
            Task.Factory.StartNew(new Action(func));  // 没有参数


            //-----------------------------------------------------Func  没有返回值类型的委托------------------------------------------------------------------
            //Func至少0个输入参数,至多16个输入参数,根据返回值泛型返回。必须有返回值,不可void。

            //Func<int> 表示没有输入参参,返回值为int类型的委托。

            //Func<object, string, int> 表示传入参数为object, string ,返回值为int类型的委托。

            //Func<object, string, int> 表示传入参数为object, string, 返回值为int类型的委托。

            //Func < T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型),返回值为int类型的委托。


            // 没有参数
            Func func78787 = delegate ()
            {
                  Console.WriteLine("func78787---------");
            };
            Task.Run(()=> { func78787(); });



            //   只有一个参数
            // action<object>
            {
                Task.Factory.StartNew(fun2, " 只有一个参数    9999999999999999999999");
                Task.Run(() => { fun2(" 只有一个参数  88888888888888888888888888  "); });
            }


            // func 方法  一个参数  有返回值类型的委托
            var s = Task<int>.Factory.StartNew(new Func<object, int>(F4),20);
            Console.WriteLine(s.Result);


            //func委托 返回值
            // 在Task 中只显示返回值  
            //有两个参数  并且有返回值
            var niuni=Task<bool>.Factory.StartNew(new Func<bool>(() => FunWithMultiPara(20, "2")));
            Console.WriteLine(niuni.Result);


            // 第一种方法 使用委托和方法
            Task task = new Task(new Action(PringtMsg));

            // 使用匿名委托
            Task taskdelegate = new Task(delegate
            {
                Console.WriteLine("hello world    taskdelegate");
            });

            //第二种 使用lamdba 表达式的方法
            Task lamdba = new Task(() => PringtMsg2());


            // 第三种方式  使用lamdba和匿名方式
            Task task_lamdba = new Task(() =>
             {
                 Console.WriteLine("hello world    task_lamdba");
             });


            task.Start();

            taskdelegate.Start();
            lamdba.Start();
            task.ContinueWith((y) => {

                Console.WriteLine("任务完成,完成时候的状态为:");
                Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", y.IsCanceled, y.IsCompleted, y.IsFaulted);
            });

            task_lamdba.Start();

            string[] messages = { "First task", "Second task", "Third task", "Fourth task" };



            foreach (var item in messages)
            {
                Task taskm = new Task((sm) => Print((string)sm), item);
                // 第二种方式
                Task t1 = new Task(() => Print222(item));
                taskm.Start();
                t1.Start();
            }

            //=============================================Task 返回值=====================================================================
            Task<int> sum = new Task<int>(() => GetSum());
            sum.Start();
            Console.WriteLine($"task result is {sum.Result}");
            //============================================= Task 返回值 =====================================================================


            =============================================传入参数   Task 返回值=====================================================================
            Task<double> ta = new Task<double>((i) => GetNum((int)i), 100);
            ta.Start();
            Console.WriteLine($"ta result is {ta.Result}");
            =============================================传入参数   Task 返回值=====================================================================

            // ========================================================================================================================
            Task<int> factory_tesk = Task.Factory.StartNew<int>((n) =>
            {
                // 这里的M变量名是不能和上面的重复的
                int M = 0;
                for (int i = 0; i <= (int)n; i++)
                {
                    M = M + i;
                }
                return M;
            }, 100);

            Console.WriteLine($"sum = {factory_tesk.Result}");
            // ========================================================================================================================


            Thread.Sleep(1100);


            Application.Run(new Form1());

            Console.Read();
        }




        private static int F5(object arg1, int arg2)
        {
            throw new NotImplementedException();
        }

        private static double GetNum(int len)
        {
            double sum = 0;
            for (int i = 0; i <= len; i++)
            {
                sum = sum + i;
                Thread.Sleep(10);
            }
            return sum;
        }

        private static int GetSum()
        {
            int sum = 0;
            for (int i = 0; i <= 10; i++)
            {
                sum = sum + i;
                Thread.Sleep(100);
            }
            return sum;
        }



        private static void Print(string msg)
        {
            Console.WriteLine($"print message : {msg}");
        }


        private static void Print222(string msg)
        {
            Console.WriteLine($"print Print222 : {msg}");
        }

        private static void PringtMsg()
        {
            Console.WriteLine("hello world");
        }

        private static void PringtMsg2()
        {
            Console.WriteLine("hello world2222 ");
        }
    }

    internal class Task<T1, T2, T3>
    {
    }
}
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值