请选择 进入手机版 | 继续访问电脑版

[C#教程] C#多线程开辟 之使命 并行库详解

[复制链接]
查看104 | 回复10 | 2021-9-14 11:20:59 | 显示全部楼层 |阅读模式
目次

媒介

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

利用 线程池可以使我们在减少并行度花销时节流 操作体系 资源。可以为 线程池是一个抽象层,其向程序员埋伏 了利用 线程的细节,使我们可以用心 处理程序逻辑,而不是各种线程标题 。

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

为了办理 这个标题 ,在.Net Framework 4.0中引入了一个新的异步操作的API,它叫使命 并行库(TPL)。

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

使命 并行库

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

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

TPL有一个关键上风 ,就是一个使命 可以通过多种方式和别的 使命 组合起来。

比如可以同时开启多个使命 ,等待全部 使命 完成,然后运行一个使命 对之前全部 使命 的结果 举行 一些计算。

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

一、创建使命

可以通过下面三种方式来创建使命 。

  1. var a1 = new Task(()=>TastMethod("线程01"));
  2. a1.Start();
  3. Task.Run(()=>TastMethod("线程001")); //已弃用
  4. Task.Factory.StartNew(()=>TastMethod("线程02"));
  5. Task.Factory.StartNew(() => TastMethod("线程03"),TaskCreationOptions.LongRunning);
  6. Console.ReadKey();
复制代码

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

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

二、利用 使命 实行 基本操作

下面先容 下从使命 中得到其计算法返回的结果 。

  1. static void Main(string[] args)
  2. {
  3. var a1 = new Task<int>(()=>TastMethod("线程01"));
  4. a1.Start();
  5. int result = a1.Result;
  6. Console.WriteLine("result:" + result);
  7. Console.ReadKey();
  8. }
  9. static int TastMethod(string name)
  10. {
  11. Console.WriteLine("线程名字:"+name+"Id:"+Thread.CurrentThread.ManagedThreadId+"是否属于线程池:"+Thread.CurrentThread.IsThreadPoolThread);
  12. return 40;
  13. }
复制代码

C#多线程开辟
之使命
并行库详解

输出结果

这里我们声明并运行了线程01并等待结果 ,该使命 会被放置在线程池中,并且主线程会等待,直到使命 返回前不停 处于壅闭 状态。

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

三、处理使命 中的非常

在异步使命 中,对于非常 的处理黑白 常告急 的。

  1. try
  2. {
  3. var a1 = new Task<int>(() => TastMethod("线程01",2));
  4. a1.Start();
  5. int result = a1.Result;
  6. Console.WriteLine("result:" + result);
  7. }
  8. catch (Exception ex)
  9. {
  10. Console.WriteLine(ex.Message);
  11. }
复制代码

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

  1. int result = a1.GetAwaiter().GetResult ;
复制代码

上面这种环境 无需封装非常 ,可以利用 GetAwaiter和GetResult方法来访问使命 结果 。

总结

到此这篇关于C#多线程开辟 之使命 并行库的文章就先容 到这了,更多干系 C#使命 并行库内容请搜索 脚本之家从前 的文章或继续欣赏 下面的干系 文章渴望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

avatar 心素如菊棺 | 2021-9-20 00:38:45 | 显示全部楼层
记得吃药!
回复

使用道具 举报

avatar 尹泽汐猩 | 2021-9-24 21:55:55 | 显示全部楼层
支持一下,下面的保持队形!
回复

使用道具 举报

avatar 春意盎然2016 | 2021-9-29 05:20:45 | 显示全部楼层
好多兽医在广场上义诊,admin楼主去看看吧!
回复

使用道具 举报

avatar 爸证欢 | 2021-9-29 20:31:38 | 显示全部楼层
灌水不是我的目的!
回复

使用道具 举报

avatar 寒郁轩良 | 2021-10-1 22:15:22 | 显示全部楼层
admin楼主,我告诉你一个你不知道的的秘密,有一个牛逼的网站,影视频道的网站所有电影和连续剧都可以免费看的。访问地址:http://tv.mxswl.com
回复

使用道具 举报

avatar 石头剪子布854 | 2021-10-2 02:19:52 | 显示全部楼层
admin楼主是在找骂么?
回复

使用道具 举报

avatar 想不到918 | 2021-10-5 11:52:00 | 显示全部楼层
以后就跟admin楼主混了!
回复

使用道具 举报

对牛弹琴的人越来越多了!
回复

使用道具 举报

顶顶更健康!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则