搜索

查看: 3054|回复: 11

[ASP.NET] .Net中Task Parallel Library的进阶用法

[复制链接]
发表于 2023-5-4 11:32:20 | 显示全部楼层 |阅读模式
Editor 2023-5-4 11:32:20 3054 11 看全部
前一篇中,了解了Task的基本用法
如果一个方法返回Task,Task,如何获取Task的返回值,获取值的过程会阻塞线程吗?
        static void Main(string[] args)
        {
            var result = DoWorkAsync().Result;
            Console.WriteLine(result);
            Console.WriteLine("我会什么时候显示");
            Console.ReadKey();
        }
        static Task DoWorkAsync()
        {
            return Task.Factory.StartNew(() =>
            {
                Thread.Sleep(3000);
                return "hello";
            });
        }

20221017114732603.png

20221017114732603.png


可见,Task的Result属性可以获取返回值,而且,获取返回值的过程线程是被阻塞的。
是否可以不阻塞线程,又能拿到某个线程的返回值呢?ContinueWith方法在某个线程结束之后进行,但同时不会阻塞线程。
        static void Main(string[] args)
        {
            DoWorkAsync().ContinueWith((pre) =>
            {
                Console.WriteLine(pre.Result);
            });
            Console.WriteLine("我会什么时候显示");
            Console.ReadKey();
        }

20221017114732604.png

20221017114732604.png


但ContinueWith总会在某个线程结束之后进行,是否可以对ContinueWith的过程控制一下呢?
        static void Main(string[] args)
        {
            DoWorkAsync().ContinueWith((pre) =>
            {
                Console.WriteLine(pre.Result);
            }, TaskContinuationOptions.NotOnFaulted);
            DoWorkAsync().ContinueWith((pre) =>
            {
                Console.WriteLine(pre.Exception);
            },TaskContinuationOptions.OnlyOnFaulted);
            Console.WriteLine("我会什么时候显示");
            Console.ReadKey();
        }
以上,当没有错误的时候就把返回值显示出来,有错误就把错误信息显示出来。
还可以通过Task的实例方法IsCompleted来判断一个线程是否完成。
        static void Main(string[] args)
        {
            var doWorkTask = DoWorkAsync();
            if (doWorkTask.IsCompleted)
            {
                Console.WriteLine(doWorkTask.Result);
            }
            else
            {
                doWorkTask.ContinueWith((pre) =>
                {
                    Console.WriteLine(pre.Result);
                }, TaskContinuationOptions.NotOnFaulted);
                doWorkTask.ContinueWith((pre) =>
                {
                    Console.WriteLine(pre.Exception);
                }, TaskContinuationOptions.OnlyOnFaulted);
            }
            
            Console.WriteLine("我会什么时候显示");
            Console.ReadKey();
        }
Task的Status属性,以及结合TaskStatus枚举,可以判断Task的状态。
        static void Main(string[] args)
        {
            var httpClient = new HttpClient();
            Task baiduTask = httpClient.GetStringAsync("http://www.baidu.com");
            var httpClient2 = new HttpClient();
            Task sinaTask = httpClient2.GetStringAsync("http://www.sina.com.cn");
            //等上面2个任务完成时这里再开始
            Task task = Task.WhenAll(baiduTask, sinaTask);
            task.ContinueWith(stringArray =>
            {
                //如果任务完成
                if (task.Status == TaskStatus.RanToCompletion)
                {
                    for (int i = 0; i
如果要控制Task的生命周期,可以考虑使用TaskCompletionSource。
       static void Main(string[] args)
        {
            AsyncFactory.GetIntAsync().ContinueWith((prev) =>
            {
                if (prev.Status == TaskStatus.RanToCompletion)
                {
                    Console.WriteLine(prev.Result);
                }
                else if (prev.Status == TaskStatus.Canceled)
                {
                    Console.WriteLine("任务被取消");
                }
                else
                {
                    Console.WriteLine("发生错误哦");
                    Console.WriteLine(prev.Exception);
                }
            });
            Console.ReadKey();
        }
    }
    public static class AsyncFactory
    {
        public static Task GetIntAsync()
        {
            var tsc = new TaskCompletionSource();
            var timer = new System.Timers.Timer(2000);
            timer.AutoReset = false;
            timer.Elapsed += (s, e) =>
            {
                tsc.SetResult(10);
                timer.Dispose();
            };
            timer.Start();
            return tsc.Task;                     
        }
    }
以上,通过TaskCompletionSource的SetResult给线程设置返回值,通过TaskCompletionSource的.Task有获取了线程。
另外,从.NET 4.5开始,Task的静态方法FromResult,接收T类型,返回Task。
        static void Main(string[] args)
        {
            var intTask = GetIntAsync();
            if (intTask.Status == TaskStatus.RanToCompletion)
            {
                Console.WriteLine(intTask.Result);
            }
            else if (intTask.Status == TaskStatus.Canceled)
            {
                Console.WriteLine("任务被取消");
            }
            else
            {
                Console.WriteLine("发生错误哦");
                Console.WriteLine(intTask.Exception);
            }
            Console.ReadKey();
        }
        static Task GetIntAsync()
        {
            return Task.FromResult(10);
        }
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对知鸟论坛的支持。如果你想了解更多相关内容请查看下面相关链接
回复

使用道具 举报

发表于 2023-6-28 19:20:02 | 显示全部楼层
123456848 2023-6-28 19:20:02 看全部
楼主太厉害了!楼主,I*老*虎*U!我觉得知鸟论坛真是个好地方!
回复

使用道具 举报

发表于 2023-6-28 21:50:00 | 显示全部楼层
落败的青春阳落s 2023-6-28 21:50:00 看全部
既然你诚信诚意的推荐了,那我就勉为其难的看看吧!知鸟论坛不走平凡路。
回复

使用道具 举报

发表于 2023-6-28 23:44:32 | 显示全部楼层
永远爱你冰塘 2023-6-28 23:44:32 看全部
楼主太厉害了!楼主,I*老*虎*U!我觉得知鸟论坛真是个好地方!
回复

使用道具 举报

发表于 2023-6-29 17:09:03 | 显示全部楼层
知足常乐77 2023-6-29 17:09:03 看全部
其实我一直觉得楼主的品味不错!呵呵!知鸟论坛太棒了!
回复

使用道具 举报

发表于 2023-6-29 17:27:09 | 显示全部楼层
十二音阶囤 2023-6-29 17:27:09 看全部
我看不错噢 谢谢楼主!知鸟论坛越来越好!
回复

使用道具 举报

发表于 2023-6-29 17:46:42 | 显示全部楼层
普通人物怨 2023-6-29 17:46:42 看全部
其实我一直觉得楼主的品味不错!呵呵!知鸟论坛太棒了!
回复

使用道具 举报

发表于 2023-6-29 18:58:14 | 显示全部楼层
贰十岁装成熟装s 2023-6-29 18:58:14 看全部
楼主发贴辛苦了,谢谢楼主分享!我觉得知鸟论坛是注册对了!
回复

使用道具 举报

发表于 2023-6-29 20:03:02 | 显示全部楼层
123456825 2023-6-29 20:03:02 看全部
论坛不能没有像楼主这样的人才啊!我会一直支持知鸟论坛
回复

使用道具 举报

发表于 2023-6-30 01:46:03 | 显示全部楼层
当当当当裤裆坦 2023-6-30 01:46:03 看全部
我看不错噢 谢谢楼主!知鸟论坛越来越好!
回复

使用道具 举报

  • 您可能感兴趣
点击右侧快捷回复 【请勿灌水】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 返回列表

RSS订阅| SiteMap| 小黑屋| 知鸟论坛
联系邮箱E-mail:zniao@foxmail.com
快速回复 返回顶部 返回列表