依枕在北江两岸的明珠~斯德哥尔摩

江湖以它的中和熨烫着地区,以它广泛的胸怀伴随着地面包车型客车荣辱跌宕。都柏林也罢,London也罢,华盛顿也罢,众多的大城市恐怕如此。

  聊到.net中的并行编制程序,恐怕你的首先影响正是Task,确实Task是三个相当灵活的用于互动编制程序的一个专用类,不可不可以认越灵活的东西用起来就越

多瑙河横贯维也纳,圣地亚哥沿江内外流淌着众多的传说。

复杂,中度封装的东西用起来很简短,然而贫乏了灵活性,那篇我们就看看这么些好用但灵活性不高的几个相互方法。

率先站是中山大学,绿软和的绿地,古朴的修建,学子的常青和那草坪一般,青青高校,未受外界纷繁,树木草地还是旺盛。那环境令人羡慕,尤其是爱读书的人到来那里,一定是有种回到家的觉得。

 

一:Invoke

 
今后电子商务的网址都不能缺少订单的流水生产线,没有订单的话网站也就未有存活的股票总值了,往往在订单提交成功后,日常会有那三个操作,第叁个:发起

信用卡扣款,第2个:发送emial确认单,那多个操作大家就能够在下单接口调用成功后,因为多少个措施是互不干扰的,所以就能够用invoke来娱乐了。

 1         static void Main(string[] args)
 2         {
 3             Parallel.Invoke(Credit, Email);
 4 
 5             Console.Read();
 6         }
 7 
 8         static void Credit()
 9         {
10             Console.WriteLine("******************  发起信用卡扣款中  ******************");
11 
12             Thread.Sleep(2000);
13 
14             Console.WriteLine("扣款成功!");
15         }
16 
17         static void Email()
18         {
19             Console.WriteLine("******************  发送邮件确认单!*****************");
20 
21             Thread.Sleep(3000);
22 
23             Console.WriteLine("email发送成功!");
24         }

第一站是大中将府。府内的摆放回到了拾0多年前。厚重的蚊帐,手摇电话,往昔熟稔的物件只是加剧了光阴的沧桑。印象最深厚的如故会议厅,想当年便是在那边,规划统一筹划伟略。

图片 1 

 

 
如何,达成起来是或不是相当粗略,只要把您须求的办法塞给invoke就行了,可是在那些措施里面有二个重载参数须求留意下,

其3站是沙面。当年的十三行。今后预留的是古朴的洋房屋修建筑。问街边卖烤红薯的父母,景点在怎么着地方,老人家某个不屑,没啥赏心悦目的,不情愿地指下对面包车型地铁沙面街。真是各有所爱啊。也或者老人家常年盘踞在此,已经对那么些构筑有了审美疲劳,在父母的眼底卖多少番薯才是主要,历史的印记并不算吗。那正是“你眼中的光景,在人家不过是常常”。

1  public static void Invoke(ParallelOptions parallelOptions, params Action[] actions);

 

有时大家的线程恐怕会跑遍全数的基本,为了坚实别的应用程序的稳定性,就要限量出席的基础,正好ParallelOptions提供了

第陆站是西关,没找到西关小姐,然则迈阿密玉女不少,一人小鲜肉和她女友你浓作者浓地分享麻辣烫。提供给雅观的女孩子的节目也不少,不外是鲜果捞,观者蒸蚌,麻辣烫,各式品牌的时髦服装,现代音乐也是少不了的。

MaxDegreeOfParallelism属性。

第4站是东山。东山的建筑整齐多了。东山的街道并不宽,旁边的房屋壹看便是有了新年了。走在大街上,1种时光悠然,恬静的气氛。再往前走,忽然发现壹块牌匾,刻的是Ssangyong戏珠。旅行便是那样-
like a box of
chocolate。你会认为麻烦和奔波是值得的。因为老是会在不经意间发现有意思的事物。小巷转转弯弯,但要么得以畅行无阻小车,也有向往而来的游人在那里拍录取景。

图片 2

 

好了,上面大家大致翻翻invoke里面包车型客车代码完毕,发现有多少个好玩的地点:

 

第四站是石室圣心大教堂。抬眼看到圣心大教堂,就以为颇为感动,宏大伟岸。假若明白了圣心大教堂的往返一定会为那座赏心悦目教堂曾经遭逢的经验唏嘘。无产阶级文化大革命局动时期具有宗教水墨画、部份拿破仑一世的彩色玻璃全被打碎,花窗被砸烂,全部经书等被烧毁,那里沦为垃圾场,直到200肆年圣心大教堂才耗费资金三千万元重新修复,成为将来伟岸气派的相貌。看到石室圣心大教堂,令人未免想起青海三明的圣约瑟天主教堂,圣约瑟天主教堂是以莲红为基调,同样宏伟瑰丽,也许是因为远在三级城市,所以并不象石室圣心大教堂那样有名,无产阶级文化大革时局动时期1样受到损坏。

<1>:
当invoke中的方法当先12个话,我们发现它走了二个internal可知的ParallelForReplicatingTask的FCL内部专用类,而那几个类是接二连三自

   Task的,当方法简单11个的话,才会走常规的Task.

<二> 居然发现了三个装exception
的ConcurrentQueue<Exception>队列集合,多少个13分入队后,再装进成AggregateException抛出来。

       比如:throw new AggregateException(exceptionQ);

<3>
大家发现,不管是超过十一个照旧小于1一个,都是通过WaitAll来等待全部的履行,所以缺点就在这一个地点,假设某三个办法执行时间太长

  
不能够脱离,那么那个主意是或不是会长久挂在那里无法出去,也就导致了主流程平昔挂起,然后页面就径直挂起,所以那么些是三个充足危险

      的表现,借使大家用task中就能够在waitall中设置二个超时时间,但invoke却无奈完结,所以在选取invoke的时候要慎重思考。

  1     try
  2     {
  3         if (actionsCopy.Length > 10 || (parallelOptions.MaxDegreeOfParallelism != -1 && parallelOptions.MaxDegreeOfParallelism < actionsCopy.Length))
  4         {
  5             ConcurrentQueue<Exception> exceptionQ = null;
  6             try
  7             {
  8                 int actionIndex = 0;
  9                 ParallelForReplicatingTask parallelForReplicatingTask = new ParallelForReplicatingTask(parallelOptions, delegate
 10                 {
 11                     for (int l = Interlocked.Increment(ref actionIndex); l <= actionsCopy.Length; l = Interlocked.Increment(ref actionIndex))
 12                     {
 13                         try
 14                         {
 15                             actionsCopy[l - 1]();
 16                         }
 17                         catch (Exception item)
 18                         {
 19                             LazyInitializer.EnsureInitialized<ConcurrentQueue<Exception>>(ref exceptionQ, () => new ConcurrentQueue<Exception>());
 20                             exceptionQ.Enqueue(item);
 21                         }
 22                         if (parallelOptions.CancellationToken.IsCancellationRequested)
 23                         {
 24                             throw new OperationCanceledException(parallelOptions.CancellationToken);
 25                         }
 26                     }
 27                 }, TaskCreationOptions.None, InternalTaskOptions.SelfReplicating);
 28                 parallelForReplicatingTask.RunSynchronously(parallelOptions.EffectiveTaskScheduler);
 29                 parallelForReplicatingTask.Wait();
 30             }
 31             catch (Exception ex2)
 32             {
 33                 LazyInitializer.EnsureInitialized<ConcurrentQueue<Exception>>(ref exceptionQ, () => new ConcurrentQueue<Exception>());
 34                 AggregateException ex = ex2 as AggregateException;
 35                 if (ex != null)
 36                 {
 37                     using (IEnumerator<Exception> enumerator = ex.InnerExceptions.GetEnumerator())
 38                     {
 39                         while (enumerator.MoveNext())
 40                         {
 41                             Exception current = enumerator.Current;
 42                             exceptionQ.Enqueue(current);
 43                         }
 44                         goto IL_264;
 45                     }
 46                 }
 47                 exceptionQ.Enqueue(ex2);
 48                 IL_264:;
 49             }
 50             if (exceptionQ != null && exceptionQ.Count > 0)
 51             {
 52                 Parallel.ThrowIfReducableToSingleOCE(exceptionQ, parallelOptions.CancellationToken);
 53                 throw new AggregateException(exceptionQ);
 54             }
 55         }
 56         else
 57         {
 58             Task[] array = new Task[actionsCopy.Length];
 59             if (parallelOptions.CancellationToken.IsCancellationRequested)
 60             {
 61                 throw new OperationCanceledException(parallelOptions.CancellationToken);
 62             }
 63             for (int j = 0; j < array.Length; j++)
 64             {
 65                 array[j] = Task.Factory.StartNew(actionsCopy[j], parallelOptions.CancellationToken, TaskCreationOptions.None, InternalTaskOptions.None, parallelOptions.EffectiveTaskScheduler);
 66             }
 67             try
 68             {
 69                 if (array.Length <= 4)
 70                 {
 71                     Task.FastWaitAll(array);
 72                 }
 73                 else
 74                 {
 75                     Task.WaitAll(array);
 76                 }
 77             }
 78             catch (AggregateException ex3)
 79             {
 80                 Parallel.ThrowIfReducableToSingleOCE(ex3.InnerExceptions, parallelOptions.CancellationToken);
 81                 throw;
 82             }
 83             finally
 84             {
 85                 for (int k = 0; k < array.Length; k++)
 86                 {
 87                     if (array[k].IsCompleted)
 88                     {
 89                         array[k].Dispose();
 90                     }
 91                 }
 92             }
 93         }
 94     }
 95     finally
 96     {
 97         if (TplEtwProvider.Log.IsEnabled())
 98         {
 99             TplEtwProvider.Log.ParallelInvokeEnd((task != null) ? task.m_taskScheduler.Id : TaskScheduler.Current.Id, (task != null) ? task.Id : 0, forkJoinContextID);
100         }
101     }

迈阿密人是否契合慢生活倒也决不可能精晓,但去到大巴定票,领票员声线和蔼,不紧相当的慢,在街边问路,地产小哥会详详细细地教导,劝告说行动是很累的比不上搭大巴,如故很令人美观的。近年来由于新科学技术兴起,电子商务大概取代了交易行业,让圣菲波哥伦比亚大学这么些以外贸为主的城池有个别受宠若惊,找不到再度攀升的着力点,但旅客照旧会欣赏那座粤味10足,充满历史的华南大都市。再不怕不知是或不是巧合,沿途看到的药材商场、水产批发很多,就在黄沙的边际,有个十分大的海产批发市镇,从沙面和圣心大教堂走出去,都能见到药材批发商场,清补凉、干大虾、甚至近年来很盛行的蔓越莓,让人觉得苏黎世真是富于生活意味的城池。

 

前阵子有消息称里斯本特许迈阿密各高校能够自行设计校服,那也说不定是为了给新德里扩大富有活力的街景吧。祝福维也纳那颗依枕在塔里木河两岸的明珠!

二:For

   下边再看看Parallel.For,大家驾驭普通的For是四个串行操作,假若说你的for中每条流程都供给实践三个办法,并且那一个主意能够互相操作且

正如耗费时间,那么为啥不尝试用Parallel.For呢,就比如下边包车型地铁代码。

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             List<Action> actions = new List<Action>() { Credit, Email };
 6 
 7             var result = Parallel.For(0, actions.Count, (i) =>
 8             {
 9                 actions[i]();
10             });
11 
12             Console.WriteLine("执行状态:" + result.IsCompleted);
13 
14             Console.Read();
15         }
16 
17         static void Credit()
18         {
19             Console.WriteLine("******************  发起信用卡扣款中  ******************");
20 
21             Thread.Sleep(2000);
22 
23             Console.WriteLine("扣款成功!");
24         }
25 
26         static void Email()
27         {
28             Console.WriteLine("******************  发送邮件确认单!*****************");
29 
30             Thread.Sleep(3000);
31 
32             Console.WriteLine("email发送成功!");
33         }
34     }

上边大家再看看Parallel.For中的最简易的重载和最复杂的重载:

1 public static ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int> body);
2 
3 public static ParallelLoopResult For<TLocal>(int fromInclusive, int toExclusive, ParallelOptions parallelOptions, Func<TLocal> localInit, Func<int, ParallelLoopState, TLocal, TLocal> body, Action<TLocal> localFinally);
4  

 

<①> 简单的重载不必多说,很简短,笔者上边的例证也演示了。

<二>
最复杂的那种重载提供了一个AOP的效果,在每二个body的action执行从前会先进行localInit那么些action,在body之后还会实施localFinally

       那个action,有未有感觉到曾经把body切成了3块?好了,上边看二个例子。

图片 3

 

图片 4图片 5

 1     static void Main(string[] args)
 2         {
 3             var list = new List<int>() { 10, 20, 30, 40 };
 4 
 5             var options = new ParallelOptions();
 6 
 7             var total = 0;
 8 
 9             var result = Parallel.For(0, list.Count, () =>
10             {
11                 Console.WriteLine("------------  thead --------------");
12 
13                 return 1;
14             },
15               (i, loop, j) =>
16               {
17                   Console.WriteLine("------------  body --------------");
18 
19                   Console.WriteLine("i=" + list[i] + " j=" + j);
20 
21                   return list[i];
22               },
23               (i) =>
24               {
25                   Console.WriteLine("------------  tfoot --------------");
26 
27                   Interlocked.Add(ref total, i);
28 
29                   Console.WriteLine("total=" + total);
30               });
31 
32             Console.WriteLine("iscompleted:" + result.IsCompleted);
33             Console.Read();
34         }

View Code

 

接下去大家再翻翻它的源代码,由于源码太多,里面无缘无故,我就找多少个好玩的地方。

<一> 
作者在里头找到了一个rangeManager分区函数,代码复杂看不懂,貌似很强劲。

 1         internal RangeManager(long nFromInclusive, long nToExclusive, long nStep, int nNumExpectedWorkers)
 2         {
 3             this.m_nCurrentIndexRangeToAssign = 0;
 4             this.m_nStep = nStep;
 5             if (nNumExpectedWorkers == 1)
 6             {
 7                 nNumExpectedWorkers = 2;
 8             }
 9             ulong num = (ulong)(nToExclusive - nFromInclusive);
10             ulong num2 = num / (ulong)((long)nNumExpectedWorkers);
11             num2 -= num2 % (ulong)nStep;
12             if (num2 == 0uL)
13             {
14                 num2 = (ulong)nStep;
15             }
16             int num3 = (int)(num / num2);
17             if (num % num2 != 0uL)
18             {
19                 num3++;
20             }
21             long num4 = (long)num2;
22             this.m_indexRanges = new IndexRange[num3];
23             long num5 = nFromInclusive;
24             for (int i = 0; i < num3; i++)
25             {
26                 this.m_indexRanges[i].m_nFromInclusive = num5;
27                 this.m_indexRanges[i].m_nSharedCurrentIndexOffset = null;
28                 this.m_indexRanges[i].m_bRangeFinished = 0;
29                 num5 += num4;
30                 if (num5 < num5 - num4 || num5 > nToExclusive)
31                 {
32                     num5 = nToExclusive;
33                 }
34                 this.m_indexRanges[i].m_nToExclusive = num5;
35             }
36         }

 

<贰> 小编又找到了那么些神奇的ParallelForReplicatingTask类。

图片 6

 

那正是说上边难题来了,在单线程的for中,笔者可以continue,能够break,那么在Parallel.For中有呢?因为是并行,所以continue基本上就从没有过

留存价值,break的话当真有价值,这几个正是寄托中的ParallelLoopState做到的,并且还新增了一个Stop。

 图片 7

 

三:ForEach

实在ForEach和for在精神上是平等的,你在源代码中会发以后底层都以调用叁个主意的,而ForEach会在底部中调用for共同的函数在此之前还会履行

任何的有个别逻辑,所以那就告知大家,能用Parallel.For的地点就无须用Parallel.ForEach,其余的都平等了,那里就不赘述了。

图片 8

 

Leave a Comment.