• Task类学习教程—Task的创建方式


     Task类学习教程—Task的创建方式

    一、简介

    ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便。比如:
    Task支持线程的取消、完成、失败通知等交互性操作,但是ThreadPool不支持;
    Task支持线程执行的先后次序,但是ThreadPool不支持;;
    以往,如果开发者要实现上述功能,需要完成很多额外的工作,现在,FCL中提供了一个功能更强大的概念:Task。Task在线程池的基础上进行了优化,并提供了更多的API。在FCL4.0中,如果我们要编写多线程程序,Task显然已经优于传统的方式。

             Task t = new Task(() =>
                {
                    Console.WriteLine("Start……");
                    //模拟工作过程
                    Thread.Sleep(5000);
                });
                t.Start();
                t.ContinueWith((task) =>
                {
                    Console.WriteLine("Already Finished,States:");
                    Console.WriteLine("IsCanceled={0}	IsCompleted={1}	IsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted);
                });
                Console.ReadKey();

    二、Task创建

    无返回值创建方式

    线程引用方法:

           static void TaskMethod(string name)
            {
                Console.WriteLine("Task: {0} is running on a thread id {1}. Is thread pool thread: {2}",
                    name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            }

    方式一:

                //方式一
                var t1 = new Task(() => TaskMethod("Task_1"));
                t1.Start();
                //等待所有任务结束 
                //任务的状态:
                //Start之前为:Created
                //Start之后为:WaitingToRun
                Task.WaitAll(t1);////等待所有任务结束 

    方式二:

                 //方式二
                Task.Run(() => TaskMethod("Task_2"));

    方式三:

                //方式三
                Task.Factory.StartNew(() => TaskMethod("Task_3")); //直接异步的方法
                 //或者
                var t3 = Task.Factory.StartNew(() => TaskMethod("Task_3"));
                Task.WaitAll(t3);//等待所有任务结束 
                //任务的状态
                //Start之前为:Running       
                //Start之后为:Running

    实例:

      class Program
        {
            static void Main(string[] args)
            {
                var t1 = new Task(() => TaskMethod("Task_1"));
                var t2 = new Task(() => TaskMethod("Task_2"));
                t2.Start();
                t1.Start();
                Task.WaitAll(t1, t2);
                Task.Run(() => TaskMethod("Task_3"));
                Task.Factory.StartNew(() => TaskMethod("Task_4"));
                //标记为长时间运行任务,则任务不会使用线程池,而在单独的线程中运行。
                Task.Factory.StartNew(() => TaskMethod("Task_5"), TaskCreationOptions.LongRunning);
    
                #region 常规的使用方式
                Console.WriteLine("主線程執行業務處理.");
                //创建任务
                Task task = new Task(() =>
                {
                    Console.WriteLine("使用System.Threading.Tasks.Task執行異步操作.");
                    for (int i = 0; i < 10; i++)
                    {
                        Console.WriteLine(i);
                    }
                });
                //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)
                task.Start();
                Console.WriteLine("主線程執行其他處理");
                task.Wait();
                #endregion
    
                Thread.Sleep(TimeSpan.FromSeconds(1));
                Console.ReadLine();
            }
    
            static void TaskMethod(string name)
            {
                Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                    name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            }
        }

    结果:

    async/await的实现方式:

     class Program
        {
            async static void AsyncFunction()
            {
                await Task.Delay(1);
                Console.WriteLine("使用System.Threading.Tasks.Task執行異步操作.");
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(string.Format("AsyncFunction:i={0}", i));
                }
            }
    
            public static void Main()
            {
                Console.WriteLine("主線程執行業務處理.");
                AsyncFunction();
                Console.WriteLine("主線程執行其他處理");
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(string.Format("Main:i={0}", i));
                }
                Console.ReadLine();
            }
        }

    结果:

    带返回值方式

    线程引用方法

           static Task<int> CreateTask(string name)
            {
                return new Task<int>(() => TaskMethod1(name));
            }
           static int TaskMethod1(string name)
            {
                Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                    name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
                Thread.Sleep(TimeSpan.FromSeconds(2));
                return 42;
            }

    方式四:

                //方式四
                Task<int> task = CreateTask("Task_1");
                task.Start();
                int result = task.Result;

    实例:

      class Program
        {
            static Task<int> CreateTask(string name)
            {
                return new Task<int>(() => TaskMethod(name));
            }
    
            static void Main(string[] args)
            {
                TaskMethod("Main Thread Task");
                Task<int> task = CreateTask("Task_1");
                task.Start();
                int result = task.Result;
                Console.WriteLine("Task_1 Result is: {0}", result);
    
                task = CreateTask("Task_2");
                //该任务会运行在主线程中
                task.RunSynchronously();
                result = task.Result;
                Console.WriteLine("Task_2 Result is: {0}", result);
    
                task = CreateTask("Task_3");
                Console.WriteLine(task.Status);
                task.Start();
    
                while (!task.IsCompleted)
                {
                    Console.WriteLine(task.Status);
                    Thread.Sleep(TimeSpan.FromSeconds(0.5));
                }
    
                Console.WriteLine(task.Status);
                result = task.Result;
                Console.WriteLine("Task_3 Result is: {0}", result);
    
                #region 常规使用方式
                //创建任务
                Task<int> getsumtask = new Task<int>(() => Getsum());
                //启动任务,并安排到当前任务队列线程中执行任务(System.Threading.Tasks.TaskScheduler)
                getsumtask.Start();
                Console.WriteLine("主線程執行其他處理");
                //等待任务的完成执行过程。
                getsumtask.Wait();
                //获得任务的执行结果
                Console.WriteLine("任務執行結果:{0}", getsumtask.Result.ToString());
                Console.ReadLine();
                #endregion
            }
    
            static int TaskMethod(string name)
            {
                Console.WriteLine("Task: {0} is running on a thread id {1}. Is thread pool thread: {2}",
                    name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
                Thread.Sleep(TimeSpan.FromSeconds(2));
                return 42;
            }
    
            static int Getsum()
            {
                int sum = 0;
                Console.WriteLine("使用Task執行異步操作.");
                for (int i = 0; i < 100; i++)
                {
                    sum += i;
                }
                return sum;
            }
        }

    结果:

    async/await的实现:

    class Program
        {
            public static void Main()
            {
                var ret1 = AsyncGetsum();
                Console.WriteLine("主線程執行其他處理");
                for (int i = 1; i <= 3; i++)
                    Console.WriteLine("Call Main()");
                int result = ret1.Result;                  //阻塞主线程
                Console.WriteLine("任務執行結果:{0}", result);
                Console.ReadLine();
            }
    
            async static Task<int> AsyncGetsum()
            {
                await Task.Delay(1);
                int sum = 0;
                Console.WriteLine("使用Task執行異步操作.");
                for (int i = 0; i < 100; i++)
                {
                    sum += i;
                }
                return sum;
            }
        }

    结果:


    技术的发展日新月异,随着时间推移,无法保证本博客所有内容的正确性。如有误导,请大家见谅,欢迎评论区指正!
    我创建了一个.NET开发交流群,用于分享学习心得和讨论相关技术难题。欢迎有兴趣的小伙伴扫码入群,相互学习!

  • 相关阅读:
    Puppet部署
    ldap命令
    openldap slapd.conf参数
    ldap objectclass
    ldap 测试表设计
    Nginx/LVS/HAProxy负载均衡软件的优缺点
    SNAT DNAT MASQUERADE 区别
    iptables常用规则
    Python中文注释报错的解决方法
    用Node.js给邮箱发送邮件
  • 原文地址:https://www.cnblogs.com/wml-it/p/14845881.html
Copyright © 2020-2023  润新知