您的位置:首页 > 其它

看看Parallel中高度封装的三个方法,Invoke,For和ForEach

2014-11-01 23:38 267 查看
  说到.net中的并行编程,也许你的第一反应就是Task,确实Task是一个非常灵活的用于并行编程的一个专用类,不可否认越灵活的东西用起来就越

复杂,高度封装的东西用起来很简单,但是缺失了灵活性,这篇我们就看看这些好用但灵活性不高的几个并行方法。

一:Invoke

  现在电子商务的网站都少不了订单的流程,没有订单的话网站也就没有存活的价值了,往往在订单提交成功后,通常会有这两个操作,第一个:发起

信用卡扣款,第二个:发送emial确认单,这两个操作我们就可以在下单接口调用成功后,因为两个方法是互不干扰的,所以就可以用invoke来玩玩了。

static void Main(string[] args)
{
Parallel.Invoke(Credit, Email);

Console.Read();
}

static void Credit()
{
Console.WriteLine("******************  发起信用卡扣款中  ******************");

Thread.Sleep(2000);

Console.WriteLine("扣款成功!");
}

static void Email()
{
Console.WriteLine("******************  发送邮件确认单!*****************");

Thread.Sleep(3000);

Console.WriteLine("email发送成功!");
}


static void Main(string[] args)
{
var list = new List<int>() { 10, 20, 30, 40 };

var options = new ParallelOptions();

var total = 0;

var result = Parallel.For(0, list.Count, () =>
{
Console.WriteLine("------------  thead --------------");

return 1;
},
(i, loop, j) =>
{
Console.WriteLine("------------  body --------------");

Console.WriteLine("i=" + list[i] + " j=" + j);

return list[i];
},
(i) =>
{
Console.WriteLine("------------  tfoot --------------");

Interlocked.Add(ref total, i);

Console.WriteLine("total=" + total);
});

Console.WriteLine("iscompleted:" + result.IsCompleted);
Console.Read();
}


View Code

接下来我们再翻翻它的源代码,由于源码太多,里面神乎其神,我就找几个好玩的地方。

<1> 我在里面找到了一个rangeManager分区函数,代码复杂看不懂,貌似很强大。

internal RangeManager(long nFromInclusive, long nToExclusive, long nStep, int nNumExpectedWorkers)
{
this.m_nCurrentIndexRangeToAssign = 0;
this.m_nStep = nStep;
if (nNumExpectedWorkers == 1)
{
nNumExpectedWorkers = 2;
}
ulong num = (ulong)(nToExclusive - nFromInclusive);
ulong num2 = num / (ulong)((long)nNumExpectedWorkers);
num2 -= num2 % (ulong)nStep;
if (num2 == 0uL)
{
num2 = (ulong)nStep;
}
int num3 = (int)(num / num2);
if (num % num2 != 0uL)
{
num3++;
}
long num4 = (long)num2;
this.m_indexRanges = new IndexRange[num3];
long num5 = nFromInclusive;
for (int i = 0; i < num3; i++)
{
this.m_indexRanges[i].m_nFromInclusive = num5;
this.m_indexRanges[i].m_nSharedCurrentIndexOffset = null;
this.m_indexRanges[i].m_bRangeFinished = 0;
num5 += num4;
if (num5 < num5 - num4 || num5 > nToExclusive)
{
num5 = nToExclusive;
}
this.m_indexRanges[i].m_nToExclusive = num5;
}
}


<2> 我又找到了这个神奇的ParallelForReplicatingTask类。



那么下面问题来了,在单线程的for中,我可以continue,可以break,那么在Parallel.For中有吗?因为是并行,所以continue基本上就没有

存在价值,break的话确实有价值,这个就是委托中的ParallelLoopState做到的,并且还新增了一个Stop。



三:ForEach

其实ForEach和for在本质上是一样的,你在源代码中会发现在底层都是调用一个方法的,而ForEach会在底层中调用for共同的函数之前还会执行

其他的一些逻辑,所以这就告诉我们,能用Parallel.For的地方就不要用Parallel.ForEach,其他的都一样了,这里就不赘述了。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐