【C# Parallel】ParallelLoopState
总结
总之,要编写一个健壮的并行循环,必须在并行循环体中检测 ParallelLoopState 对象的 IsExceptional, IsStopped 和 LowestBreakIteration 三个属性,出于简化编程的目的, ParallelLoopState 提供了一个 ShouldExitCurrentIteration 属性,当Stop()\cancel()时,ShouldExitCurrentIteration等于true。
| 方法 | 属性 | |
| 异常 | IsExceptional | ShouldExitCurrentIteration |
| Stop | IsStopped | ShouldExitCurrentIteration |
| Break | LowestBreakIteration(循环索引起始是0) |
stop
可以多次被调用,对应的属性IsExceptional、IsStopped。当发生break后,IsStopped等于true,ShouldExitCurrentIteration等于true。

ParallelLoopResult plr= Parallel.For(1,20,(index, LoopState) =>{
if (i == 10)
{
// 当某一个循环单元的数==10,
// 则停止所有线程的Parallel.For的执行,已经执行循环执行完当前一轮循环后停止,未执行的循环直接停止执行。
LoopState.Stop();//执行Stop()LowestBreakIteration为空,Stop/Break互斥两个只能有一个执行,Stop停止循环比Break快。
Console.WriteLine("ShouldExitCurrentIteration " + LoopState.ShouldExitCurrentIteration);//break 执行后ShouldExitCurrentIteration为true
return;//不加return,可能会发生该进程资源未释放。
}
Console.WriteLine(index+ " ThreadId" + Environment.CurrentManagedThreadId);
});
Console.WriteLine("LowestBreakIteration:" + plr.LowestBreakIteration);
break
可以多次被调用。对应的属性LowestBreakIteration、ShouldExitCurrentIteration。当发生break后,LowestBreakIteration等于最小那个index,ShouldExitCurrentIteration等于false
由于多线程执行,所以会有多个线程同时发生break,LowestBreakIteration取for循环最小那个index 。

ParallelLoopResult plr= Parallel.For(1,20,(index, LoopState) =>{
if (index == 10)
{
// 当某一个循环单元的数==10,
// 则首先停止当前 线程的Parallel.For的执行
//其他线程的For 满足条件则继续执行,直到满足条件或完成
// 所有执行单元结束后退出Parallel.For的执行
LoopState.Break();//LowestBreakIteration有值,Stop/Break互斥两个只能有一个执行,Stop停止循环比Break快。
Console.WriteLine("ShouldExitCurrentIteration " + LoopState.ShouldExitCurrentIteration);//break 执行后对ShouldExitCurrentIteration为false 没影响
return;//不加return,可能会发生该进程资源未释放。
}
Console.WriteLine(index+ " ThreadId" + Environment.CurrentManagedThreadId);
});
Console.WriteLine("LowestBreakIteration:" + plr.LowestBreakIteration);
CancellationTokenSource 取消并行
namespace CancelParallelLoops
{
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks; class Program
{
static void Main()
{
int[] nums = Enumerable.Range(0, 10000000).ToArray();
CancellationTokenSource cts = new CancellationTokenSource(); // Use ParallelOptions instance to store the CancellationToken
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;
po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
Console.WriteLine("Press any key to start. Press 'c' to cancel.");
Console.ReadKey(); // Run a task so that we can cancel from another thread.
Task.Factory.StartNew(() =>
{
if (Console.ReadKey().KeyChar == 'c')
cts.Cancel();
Console.WriteLine("press any key to exit");
}); try
{
Parallel.ForEach(nums, po, (num) =>
{
double d = Math.Sqrt(num);
Console.WriteLine("{0} on {1}", d, Thread.CurrentThread.ManagedThreadId);
});
}
catch (OperationCanceledException e)
{
Console.WriteLine(e.Message);
}
finally
{
cts.Dispose();
} Console.ReadKey();
}
}
}
IsExceptional 属性(不知道如何使用)
ParallelLoopState 的 IsExceptional 属性为 true ,ShouldExitCurrentIteration等于true。
ShouldExitCurrentIteration 属性
总之,要编写一个健壮的并行循环,必须在并行循环体中检测 ParallelLoopState 对象的 IsExceptional, IsStopped 和 LowestBreakIteration 三个属性,出于简化编程的目的, ParallelLoopState 提供了一个 ShouldExitCurrentIteration 属性,当Stop()\cancel()时,ShouldExitCurrentIteration等于true。
Stop和Break
可以分别用来控制Parallel.For的执行。
Stop表示Parallel.For的执行立刻停止,无论其他执行单元是否达到停止的条件。
Break表示满足条件的当前执行单元立刻停止,而对于其他执行单元,其中满足停止条件也会通过Break停止,其他未满足停止条件的则会继续执行下去,从而全部执行完毕,自然停止。当所有执行单元停止后,Parallel.For函数才停止执行并退出。
执行Stop()LowestBreakIteration为空, LoopState.Break();LowestBreakIteration有值,Stop/Break互斥两个只能有一个执行,Stop停止循环比Break快。
break类似于for的continue,而stop就类似于for的break。
【C# Parallel】ParallelLoopState的更多相关文章
- 【C# Parallel】开端
使用条件 1.必须熟练掌握锁.死锁.task的知识,他是建立这两个的基础上的.task建立在线程和线程池上的. 2.并不是所有代码都适合并行化. 例如,如果某个循环在每次迭代时只执行少量工作,或它在很 ...
- 【C# Parallel】ParallelOptions
ParallelOptions 构造函数 此构造函数用默认值初始化实例. MaxDegreeOfParallelism 初始化为-1,表示没有对应采用的并行度进行上限设置. CancellationT ...
- 【知识点整理】Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和执行速度的比较
[知识点整理]Oracle中NOLOGGING.APPEND.ARCHIVE和PARALLEL下,REDO.UNDO和执行速度的比较 1 BLOG文档结构图 2 前言部分 2.1 导读和注意事项 ...
- 【静默安装】configToolAllCommands响应文件问题
[静默安装]configToolAllCommands响应文件问题 客户在静默安装RAC 12.1.0.2的时候有如下的输出: Successfully Setup Software. As inst ...
- 【Unity Shaders】学习笔记——渲染管线
[Unity Shaders]学习笔记——Shader和渲染管线 转载请注明出处:http://www.cnblogs.com/-867259206/p/5595924.html 写作本系列文章时使用 ...
- 【exp/imp】将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中
[exp/imp]将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中 1.1 BLOG文档结构图 1.2 前言部分 1.2.1 导读和注意事项 各位技术爱好者,看完本文后 ...
- 【新特性】JDK1.8
一.简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性.在本文中我们将学习这些新特性,并用实际的 ...
- 【OCP|OCM】Oracle培训考证系列
[OCP|OCM]Oracle培训考证系列 我的个人信息 网名:小麦苗 QQ:646634621 QQ群:618766405 我的博客:http://blog.itpub.net/26736162 ...
- 【大数据】Scala学习笔记
第 1 章 scala的概述1 1.1 学习sdala的原因 1 1.2 Scala语言诞生小故事 1 1.3 Scala 和 Java 以及 jvm 的关系分析图 2 1.4 Scala语言的特点 ...
随机推荐
- MySQL环境变量配置方法
MySQL配置方法 下载免安装版本的MySQL数据库,大家根据自己的开发环境下载对应版本的数据库,我在此举例的是Windows系统下的配置方法,下载地址如下: https://dev.mysql.co ...
- golang中的tcp编程
1. tcp server package main import ( "bufio" "fmt" "net" ) func main() ...
- golang中数组指针和指针数组当做函数参数如何修改数组中的值
先理解:数组指针它的类型时指针,指针数组它的类型时数组 1. 数组指针当做函数的参数 package main import "fmt" func changeData(dataA ...
- 学习JAVAWEB第九天
## XML: 1. 概念:Extensible Markup Language 可扩展标记语言 * 可扩展:标签都是自定义的. <user> <student> * 功能 * ...
- 学习JAVAWEB第五天
# 今日内容 1. JavaScript基础 ## JavaScript: * 概念: 一门客户端脚本语言 * 运行在客户端浏览器中的.每一个浏览器都有JavaScript的解析引擎 * 脚本语言:不 ...
- 使用pybind11为Python编写C++扩展(一)配置篇:Build(编译和链接)
目录 Setuptools CMake 最后决定选用pybind11,理由如下: 比python原生的C API看起来人性多了 我的C++代码不是现成的,需要一定的C++开发工作量,所以感觉cytho ...
- Pycharm 使用备忘
1.打开方法定义 快捷方式:[ctrl+左键]或者[Ctrl+B] 如果点击之后,打开不是[.py]文件,而是[.pyi]文件,可以把下面红框的参数删掉. 2.设置文件开头默认注释 # *_* cod ...
- django之memcached缓存系统
django其他缓存方法:(https://www.cnblogs.com/jishuweiwang/p/6110809.html) memcached版本 <1.5 1. memcached缓 ...
- JavaScript闭包的那些事
JavaScript闭包 1.函数在JavaScript中的地位 在介绍闭包之前,可以先聊聊函数在JavaScript中的地位,因为闭包的存在是与函数息息相关的. JavaScript之所以可以称之为 ...
- Android基本控件Spinner的简单使用【转】
Android基本控件Spinner的简单使用 感谢大佬:https://blog.csdn.net/bingocoder/article/details/80469939 学习过了Textview, ...