C#多线程开发之任务并行库详解

 更新时间:2021年09月09日 11:29:44   作者:阿辉  
最近在学习C#的并行编程,在每本书上的看到的知识点都不全面,所以先参考多本书书籍的讲解,将并行编程,多线程编程的知识点整理一下,这篇文章主要给大家介绍了关于C#多线程开发之任务并行库的相关资料,需要的朋友可以参考下

前言

之前学习了线程池,知道了它有很多好处。

使用线程池可以使我们在减少并行度花销时节省操作系统资源。可认为线程池是一个抽象层,其向程序员隐藏了使用线程的细节,使我们可以专心处理程序逻辑,而不是各种线程问题。

但也不是说我们所有的项目中都上线程池,其实它也有很多弊端,比如我们需要自定义使用异步委托的方式才可以将线程中的消息或异常传递出来。这些如果在一个大的软件系统中,会导致软件结构过于混乱,各个线程之间消息传递来传递去的,如果发生没有处理掉的异常,很容易导致软件出现致命错误。

为了解决这个问题,在.Net Framework 4.0中引入了一个新的异步操作的API,它叫任务并行库(TPL)。

那么接下来,让我们一起来认识一下这个TPL,看看它到底有什么魔力可以把线程池中的棘手问题解决掉。

任务并行库

TPL又被认为是线程池的有一个抽象,其对程序员隐藏了线程池交互的底层代码,并只提供了更方便的细粒度的API。

TPL的核心是任务。一个任务代表一个异步操作,该操作可以通过多种方式运行,可以使用或不使用独立线程运行。

TPL有一个关键优势,就是一个任务可以通过多种方式和其它任务组合起来。

比如可以同时开启多个任务,等待所有任务完成,然后运行一个任务对之前所有任务的结果进行一些计算。

可以使用AggregateException来捕获底层任务内部所有异常,并允许单独处理这些异常。在C#5.0中已经内置了对TPL的支持,允许我们使用心得await和async关键字以平滑的、舒服的方式操作任务。

一、创建任务

可以通过下面三种方式来创建任务。

      var a1 = new Task(()=>TastMethod("线程01"));
      a1.Start();

      Task.Run(()=>TastMethod("线程001"));    //已弃用
      Task.Factory.StartNew(()=>TastMethod("线程02"));
      Task.Factory.StartNew(() => TastMethod("线程03"),TaskCreationOptions.LongRunning);

      Console.ReadKey();

在最新的.NET 5.0中已经将任务快速启动方式Run,丢弃掉了。只能使用其余的两种。实例化的Tast属性,必须进行启动,任务才可以执行。其余的.NET已经做了内置,只需要使用就默认自动开启。

在线程3开启过程中,增加了TaskCreationOptions.LongRuning参数,它表示标记该任务为长时间运行,结果该任务将不会使用线程池,而在单独的线程中运行。然而根据运行该任务的当前任务调度程序,运行方式可能不同。

二、使用任务执行基本操作

下面介绍下从任务中得到其计算法返回的结果。

        static void Main(string[] args)
        {   
            var a1 = new Task<int>(()=>TastMethod("线程01"));
            a1.Start();
            int result = a1.Result;            
            Console.WriteLine("result:" + result);
            Console.ReadKey();
        }

        static int TastMethod(string name) 
        {
            Console.WriteLine("线程名字:"+name+"Id:"+Thread.CurrentThread.ManagedThreadId+"是否属于线程池:"+Thread.CurrentThread.IsThreadPoolThread);
            return 40;
        }

输出结果

这里我们声明并运行了线程01并等待结果,该任务会被放置在线程池中,并且主线程会等待,直到任务返回前一直处于阻塞状态。

其实也可以调用方法RunSynchronously()方法,使其特定运行在主线程。这是一个非常好的优化,可以避免使用线程池来执行非常短暂的操作。

三、处理任务中的异常

在异步任务中,对于异常的处理是非常重要的。

            try
            {
                var a1 = new Task<int>(() => TastMethod("线程01",2));
                a1.Start();
                int result = a1.Result;
                Console.WriteLine("result:" + result);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }      

当程序启动时,创建了一个任务并尝试同步获取任务结果。Result属性的Get部分会使当前线程等待直到该任务结束,并将异常传播给当前线程。此时通过try/catch是很容易捕获到的(需要注意AggregateExceptiont,它被封装起来,)。

int result = a1.GetAwaiter().GetResult ;

上面这种情况无需封装异常,可以使用GetAwaiter和GetResult方法来访问任务结果。

总结

到此这篇关于C#多线程开发之任务并行库的文章就介绍到这了,更多相关C#任务并行库内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c#使用简单工厂模式实现生成html文件的封装类分享

    c#使用简单工厂模式实现生成html文件的封装类分享

    这篇文章主要介绍了运用了简单工厂模式实现页面静态化封装类,思路比较简单,大家可根据自己的思路再扩展此类
    2014-01-01
  • C#实现显示CPU使用率与内存使用率

    C#实现显示CPU使用率与内存使用率

    这篇文章主要为大家详细介绍了如何利用C#实现显示CPU使用率与内存使用率,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以了解一下
    2022-12-12
  • C#传值方式实现不同程序窗体间通信实例

    C#传值方式实现不同程序窗体间通信实例

    Form2构造函数中接收一个string类型参数,即Form1中选中行的文本,将Form2的TextBox控件的Text设置为该string,即完成了Form1向Form2的传值
    2013-12-12
  • C# WinForm 判断程序是否已经在运行,且只允许运行一个实例,附源码

    C# WinForm 判断程序是否已经在运行,且只允许运行一个实例,附源码

    本文主要介绍WinFrom程序中只允许运行一个实例的方法,并有完整的代码示例,希望能给需要的朋友一些帮助。
    2016-04-04
  • 使用Log4net进行日志记录

    使用Log4net进行日志记录

    本文详细讲解了使用Log4net进行日志记录的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • UnityRTS实现相机移动缩放功能

    UnityRTS实现相机移动缩放功能

    这篇文章主要为大家详细介绍了UnityRTS实现相机的移动缩放功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03
  • C# 实现FTP客户端的小例子

    C# 实现FTP客户端的小例子

    这篇文章主要介绍了C# 如何实现FTP客户端,文中实例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • C#实现HTTP下载文件的方法

    C#实现HTTP下载文件的方法

    这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下
    2014-11-11
  • 解决C#调用dll提示

    解决C#调用dll提示

    下面小编就为大家分享一篇解决C#调用dll提示"试图加载格式不正确的程序"问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • 使用C#创建Windows服务的实例代码

    使用C#创建Windows服务的实例代码

    这篇文章主要介绍了使用C#创建Windows服务的实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07

最新评论