• Task Parallel Library01,基本用法


    我们知道,每个应用程序就是一个进程,一个进程有多个线程。Task Parallel Library为我们的异步编程、多线程编程提供了强有力的支持,它允许一个主线程运行的同时,另外的一些线程或Task也同时运行。本篇体验基本用法。

    基本用法

     

    Taks的构造函数接收的类型是Action,也就是一个委托。

            static void Main(string[] args)
    
            {
    
                var t1 = new Task(() =>
    
                {
    
                    Console.WriteLine("任务1开始");
    
                    Thread.Sleep(1000);
    
                    Console.WriteLine("任务1结束");
    
                });
    
                t1.Start();
    
                Console.ReadKey();
    
            }

    如果把方法放到外面。

            static void Main(string[] args)
    
            {
    
                var t1 = new Task(() => DoSth(1,2000));
    
                t1.Start();
    
                Console.ReadKey();
    
            }
    
            static void DoSth(int id, int sleepTime)
    
            {
    
                Console.WriteLine("任务{0}开始",id);
    
                Thread.Sleep(sleepTime);
    
                Console.WriteLine("任务{0}结束",id);
    
            }
    

    如果有多个Task同时执行。

            static void Main(string[] args)
    
            {
    
                var t1 = new Task(() => DoSth(1,2000));
    
                t1.Start();
    
                var t2 = new Task(() => DoSth(2, 1500));
    
                t2.Start();
    
                var t3 = new Task(() => DoSth(3, 3000));
    
                t3.Start();
    
                Console.ReadKey();
    
            }
    


         
    1 

    如果有很多Task,每个Task手动启动的话很费事,Task Parallel Library为我们准备了Task工厂。

            static void Main(string[] args)
    
            {
    
                var t1 = Task.Factory.StartNew(() => DoSth(1, 2000));
    
                var t2 = Task.Factory.StartNew(() => DoSth(2, 1500));
    
                var t3 = Task.Factory.StartNew(() => DoSth(3, 3000));
    
                Console.ReadKey();
    
            }
    

    如果我们想在一个任务结束之后立即执行某个任务,可以使用ContinueWith方法。

            static void Main(string[] args)
    
            {
    
                var t1 = Task.Factory.StartNew(() => DoSth(1, 2000)).ContinueWith((pre)=> DoOtherThing(4,2000)); 
    
                var t2 = Task.Factory.StartNew(() => DoSth(2, 1500));
    
                var t3 = Task.Factory.StartNew(() => DoSth(3, 3000));
    
                Console.ReadKey();
    
            }
    
            static void DoSth(int id, int sleepTime)
    
            {
    
                Console.WriteLine("任务{0}开始",id);
    
                Thread.Sleep(sleepTime);
    
                Console.WriteLine("任务{0}结束",id);
    
            }
    
            static void DoOtherThing(int id, int sleepTime)
    
            {
    
                Console.WriteLine("其他任务{0}开始", id);
    
                Thread.Sleep(sleepTime);
    
                Console.WriteLine("其他任务{0}结束", id);
    
            }
    

    如果希望等待所有的Task执行完毕,使用WaitAll方法。

            static void Main(string[] args)
    
            {
    
                var t1 = Task.Factory.StartNew(() => DoSth(1, 2000));
    
                var t2 = Task.Factory.StartNew(() => DoSth(2, 1500));
    
                var t3 = Task.Factory.StartNew(() => DoSth(3, 3000));
    
                var taskList = new List<Task> {t1, t2, t3};
    
                Task.WaitAll(taskList.ToArray());
    
                Console.WriteLine("我是在所有Task执行完毕后才执行的");
    
                Console.ReadKey();
    
            }
    

    如果想手动取消结束某个Task,需要为方法带上CancellationToken类型参数。

            static void Main(string[] args)
    
            {
    
                var source = new CancellationTokenSource();
    
                try
    
                {
    
                    var t1 =
    
                        Task.Factory.StartNew(() => DoSth(1, 1000, source.Token))
    
                            .ContinueWith((pre) => DoOtherThing(2, 2000));
    
                    source.Cancel();
    
                }
    
                catch (Exception ex)
    
                {
    
                    Console.WriteLine(ex.GetType());
    
                }
    
                Console.WriteLine("haha");
    
                Console.ReadKey();
    
            }
    
            static void DoSth(int id, int sleepTime, CancellationToken token)
    
            {
    
                if (token.IsCancellationRequested)
    
                {
    
                    Console.WriteLine("任务被取消");
    
                    token.ThrowIfCancellationRequested();
    
                }
    
                
    
                Console.WriteLine("任务{0}开始",id);
    
                Thread.Sleep(sleepTime);
    
                Console.WriteLine("任务{0}结束",id);
    
            }
    
            static void DoOtherThing(int id, int sleepTime)
    
            {
    
                Console.WriteLine("其他任务{0}开始", id);
    
                Thread.Sleep(sleepTime);
    
                Console.WriteLine("其他任务{0}结束", id);
    
            }
    

    2

    如何从Task从获取方法的返回结果呢?

            static void Main(string[] args)
    
            {
    
                Console.WriteLine("开始计算");
    
                Task<int> t = Task.Factory.StartNew(() => Sum(1, 2));
    
                Console.WriteLine("等待结果");
    
                Console.WriteLine(t.Result);
    
                Console.ReadKey();
    
            }
    
            static int Sum(int a, int b)
    
            {
    
                return a + b;
    
            }
    

    后面一个Task获取前面一个Task的返回值。

            static void Main(string[] args)
    
            {
    
                Task<string> firstTask = Task.Factory.StartNew<string>(() =>
    
                {
    
                    Console.WriteLine("第一个任务开始");
    
                    return "hi from the one";
    
                });
    
                Task secondTask = firstTask.ContinueWith((prevoursTask) =>
    
                {
    
                    Console.WriteLine("这里是第二个任务,获取到第一个任务的返回值是{0}",prevoursTask.Result,TaskContinuationOptions.OnlyOnRanToCompletion);
    
                });
    
                secondTask.Wait();
    
                Console.ReadKey();
    
            }
    

    等待所有Task完成。

            static void Main(string[] args)
    
            {
    
               var t1 =  Task.Factory.StartNew(() =>
    
                {
    
                    Console.WriteLine("第一个任务");
    
                    Thread.Sleep(1000);
    
                });
    
                var t2 = Task.Factory.StartNew(() =>
    
                {
    
                    Console.WriteLine("第二个任务");
    
                    Thread.Sleep(1000);
    
                });
    
                var taskList = new List<Task> {t1, t2};
    
                Task.Factory.ContinueWhenAll(taskList.ToArray(), (t) => { Console.WriteLine("所有任务完成我就出来"); });
    
                Console.ReadKey();
    
            }
    

    如果是嵌套Task。

            static void Main(string[] args)
    
            {
    
                Task.Factory.StartNew(() =>
    
                {
    
                    Task child = Task.Factory.StartNew(() =>
    
                    {
    
                        Console.WriteLine("我是子任务");
    
                    }, TaskCreationOptions.AttachedToParent);
    
                }).Wait();
    
                Console.ReadKey();
    
            }

    启动Task的几种方式

     

    1、通过Task.Factory.StartNew方法。

            static void Main(string[] args)
    
            {
    
                Task.Factory.StartNew(() => SaySth("hello"));
    
                Console.ReadKey();
    
            }
    
            static void SaySth(string msg)
    
            {
    
                Console.WriteLine(msg);
    
            }
    

    2、通过Task的Start实例方法

            static void Main(string[] args)
    
            {
    
                var t = new Task(() => SaySth("hello"));
    
                t.Start();
    
                Console.ReadKey();
    
            }

    或者干脆用委托。

            static void Main(string[] args)
    
            {
    
                Task t = new Task(delegate {SaySth("hello");});
    
                t.Start();
    
                Console.ReadKey();
    
            }


     

    3、Task的静态方法Run

            static void Main(string[] args)
    
            {
    
                Task t = Task.Run(() => SaySth("hello"));
    
                Console.ReadKey();
    
            }
    
            static void SaySth(string msg)
    
            {
    
                Console.WriteLine(msg);
    
            }      
    


    一个例子

     

    比如说要下载某个页面,在保持当前UI界面无影响的情况下,使用Task在后台启动任务下载某个页面。

            static void Main(string[] args)
    
            {
    
                Console.WriteLine("界面内容");
    
                Task<string> r = DownloadAsync("http://www.baidu.com");
    
                while (!r.IsCompleted)
    
                {
    
                    Console.Write(".");
    
                    Thread.Sleep(250);
    
                }
    
                Console.WriteLine(r.Result);
    
                Console.ReadKey();
    
            }
    
            private static string DownloadWebPage(string url)
    
            {
    
                WebRequest request = WebRequest.Create(url);
    
                WebResponse response = request.GetResponse();
    
                var reader = new StreamReader(response.GetResponseStream());
    
                return reader.ReadToEnd();
    
            }
    
            private static Task<string> DownloadAsync(string url)
    
            {
    
                return Task.Factory.StartNew(() => DownloadWebPage(url));
    
            }
    
  • 相关阅读:
    核函数矩阵为什么要是positive semidefinite的
    Autoencoders
    Statistics与Machine Learning有什么区别
    [zz]Using SyncTeX with LaTeX
    Metric Learning的一个疑惑
    [zz]Latex中texworks编辑器正向反向跳转搜索
    [zz]Python3.x新特性
    LyX 2.0.5中文排版
    function
    多行文字结尾显示省略号
  • 原文地址:https://www.cnblogs.com/darrenji/p/4436411.html
Copyright © 2020-2023  润新知