文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

.Net中TaskParallelLibrary的基本用法

2024-04-02 19:55

关注

我们知道,每个应用程序就是一个进程,一个进程有多个线程。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();
        }

如果有很多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);
        }

如何从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));
        }

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对编程网的支持。如果你想了解更多相关内容请查看下面相关链接

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯