关于Parallel我也不细说了,一则微软封装的很好用,二来介绍这个的遍地都是。

  我要说的是,要想成为一个优秀的标题党,一定要把重点放到别的地方,为了节省大家阅读时间,我先把结论说了,然后再慢慢从头说,愿意往下看的可以看看因果,不愿意看的,也算咱给大家提个醒吧。

  结论就是,大家在做单元测试用例的时候一定要用心,这篇随笔是要检讨并警醒下自己并与大家共勉。

  据一些我不记得名字的国外权威专家,据说是测试大师级人物研究,测试用例的出现的错误并不比被测试的代码少,我相信大多数人会和我类似,在写代码的时候小心翼翼,但是为代码编写单元测试及用例的时候往往注意力下意识的不那么集中,今天就是这么个情况。可能是缺乏锻炼(我天天打太极拳的。。。)的原因,连续几个晚上由于学习原因睡的比较晚,今天就比较困,然后干了件点题的事。

  我写了一个对象ID生成器,以时间戳和顺序号组合,虽然不支持集群,但是目前情况下足够了,然后因为复制数据库的同事坚决不同意将主键的int类型改掉,那怕改成bigint都不同意。。。跑题了。总之,各种限制的情况下出了这么个东西:

  //不能再集群情况下使用
public class IDGenerator
{
     private static double _seconds = 0;
private static int _sequenceIndex = 0;
private static object _lock = new object();
     private static ReaderWriterLockSlim writerLock = new ReaderWriterLockSlim();
private static IDGenerator _instance; private IDGenerator()
{
} public static int NewID
{
get
{
int newID = IDGenerator.Instance.CreateNewID();
return newID;
}
} private int CreateNewID()
{
string id; writerLock.EnterReadLock();
try
{
id = BuildIDAndUpdateSead();
}
finally//保证退出锁
{
writerLock.ExitReadLock();
}
int newID = TypeParseHelper.GetIntValueByString(id);
return newID;
} private string BuildIDAndUpdateSead()
{
double seconds;
bool isEqualSecondsCount;
seconds = InterceptSecondsInTicks(); isEqualSecondsCount = seconds.Equals(_seconds);
if (isEqualSecondsCount)
{
         bool isUpperBound = _sequenceIndex == ;
if (isUpperBound)
{
Thread.Sleep();
_sequenceIndex = ;
_seconds++;
}
          else
          {
  Interlocked.Increment(ref _sequenceIndex);
          }
}
else
            {
_seconds = seconds;
}
string id = _seconds.ToString() + _sequenceIndex.ToString().PadLeft(, '');
return id;
} private double InterceptSecondsInTicks()
{
DateTime currentDate = DateTime.Now;
long elapsedTicks = (currentDate.Ticks - ConstantGather.BEGIN_STANDARD_TICKS);
TimeSpan elapsedSpan = new TimeSpan(elapsedTicks);
double seconds = Math.Floor(elapsedSpan.TotalSeconds);
return seconds;
} private static IDGenerator Instance
{
get
{
if (_instance != null)
{
return _instance;
} lock (_lock)
{
if (_instance == null)
{
_instance = new IDGenerator();
}
} return _instance;
}
}
}

  做完了,当然要写点单元测试测试一下,就先写了个同步的,然后写了个异步的,然后写了个并发的

       public List<int> GenerateRequisitionIDs()
{
TaskFactory taskFactory = new TaskFactory();
Task<int>[] tasks = new Task<int>[] {
taskFactory.StartNew(() => GenerateRequisitionID()),
taskFactory.StartNew(() => GenerateRequisitionID()),
taskFactory.StartNew(() => GenerateRequisitionID()) }; var query = tasks.Where(t => !t.Result.Equals())
.Select(t => t.Result);
return query.ToList();
}

  高潮来了,然后我在单元测试里顺手写了个并行的。。。

Parallel.For(, actual, c =>
{
int id = target.GenerateRequisitionID();
list.AddLast(id);
});

  测试结果就不停得出错,我费了很大功夫定位到了出错的位置。。。

string idStr = _seconds.ToString() + "-" + _sequenceIndex.ToString().PadLeft(, '');

  这一句是我写了一堆定位错误的代码中的一句,发现了个奇怪的现象,这个字符串赋值后,两边居然是不一样的,而且这一句在排它锁里。。。

  并行的用法应该是将一对任务,平均分开,各自做各自的,互相不影响,问题就在于我这生成器是个单例。。。

  作为一个敬业的标题党,并发和并行的区别我就不说了,反正连百度都知道的事。。。  

  最后说一句,单元测试要认真,单元测试的代码哪怕随便玩的也要组织好,不要乱放,不要完全不着边的都测,正常业务里是不会有并行生成ID的场景的,这个测试没有意义,而且,如果看了生成器的代码会发现,由于int32本身的长度问题,我限定了一秒最多能生成999个ID,我需要测的其实不是并行问题,太晚了,思维比较跳跃,就这么着吧,下次长点记性就好了,以上。

Parallel并行之乱用的更多相关文章

  1. Parallel并行编程初步

    Parallel并行编程可以让我们使用极致的使用CPU.并行编程与多线程编程不同,多线程编程无论怎样开启线程,也是在同一个CPU上切换时间片.而并行编程则是多CPU核心同时工作.耗时的CPU计算操作选 ...

  2. C# IEnumerable,Lambda表达式和 Parallel并行编程的用法

    以前一直主要做C++和C方面的项目,对C#不太了解熟悉,但听说不难,也就一直没有在意学习C#方面的知识.今天有个C#项目,需要做些应用的扩展,同时修改一些bug.但看了C#代码,顿时觉得有些不适应了. ...

  3. Parallel并行编程

    Parallel并行编程 Parallel并行编程可以让我们使用极致的使用CPU.并行编程与多线程编程不同,多线程编程无论怎样开启线程,也是在同一个CPU上切换时间片.而并行编程则是多CPU核心同时工 ...

  4. C# 使用Parallel并行开发Parallel.For、Parallel.Foreach实例

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...

  5. list.stream().parallel() 并行流

    https://blog.csdn.net/u011001723/article/details/52794455/  :  parallel()其实就是一个并行执行的流.它通过默认的ForkJoin ...

  6. Stream parallel并行流的思考

    1.并行流并不一定能提高效率,就和多线程并不能提高线程的效率一样 因为引入并行流会引起额外的开销,就像线程的频繁上下文切换会导致额外的性能开销一样,当数据在多个cpu中的处理时间小于内核之间的传输时间 ...

  7. .net Parallel并行使用注意事项

    因项目响应过慢,代码优化空间不大,在暂时无法调整系统架构的情况下,只有使用.NET中的TPL解决一些模块耗时过多的问题.但在使用过程中也碰到了一些问题,现在把它写下来,用于备忘. 1. Paralle ...

  8. .net Parallel并行使用

    因项目响应过慢,代码优化空间不大,在暂时无法调整系统架构的情况下,只有使用.NET中的TPL解决一些模块耗时过多的问题.但在使用过程中也碰到了一些问题,现在把它写下来,用于备忘. 1. Paralle ...

  9. oracle使用parallel并行,多线程查询

    insert into tmp (select /*parallel (a, 4)*/ * from plsuer.as_cdrindex_info_h partition(P_20170430) w ...

随机推荐

  1. NuGet镜像上线试运行

    为解决国内访问NuGet服务器速度不稳定的问题,我们用阿里云服务器搭建了一个NuGet镜像,目前已上线试运行. 使用NuGet镜像源的方法如下: 1)NuGet镜像源地址:https://nuget. ...

  2. 札记:android手势识别,MotionEvent

    摘要 本文是手势识别输入事件处理的完整学习记录.内容包括输入事件InputEvent响应方式,触摸事件MotionEvent的概念和使用,触摸事件的动作分类.多点触摸.根据案例和API分析了触摸手势T ...

  3. Sublime Text 3中文乱码解决方法以及安装包管理器方法

    一般出现乱码是因为文本采用了GBK编码格式,Sublime Text默认不支持GBK编码. 安装包管理器 简单安装 使用Ctrl+`快捷键或者通过View->Show Console菜单打开命令 ...

  4. C#基础篇 - 理解委托和事件

    1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托是C#中类型安全的,可以订阅一个或多个具有相同签名方法的函数指针.简单理解,委托是一种可以把函数当做参数传递的类型.很多情况下,某 ...

  5. ASP.NET Core应用针对静态文件请求的处理[3]: StaticFileMiddleware中间件如何处理针对文件请求

    我们通过<以Web的形式发布静态文件>和<条件请求与区间请求>中的实例演示,以及上面针对条件请求和区间请求的介绍,从提供的功能和特性的角度对这个名为StaticFileMidd ...

  6. [C#] 进阶 - LINQ 标准查询操作概述

    LINQ 标准查询操作概述 序 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> ...

  7. 【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇一:WPF常用知识以及本项目设计总结

    篇一:WPF常用知识以及本项目设计总结:http://www.cnblogs.com/baiboy/p/wpf.html 篇二:基于OneNote难点突破和批量识别:http://www.cnblog ...

  8. Git时间(第一次写,这个怎么玩啊)

    1.安装 Liunx直接打开shell界面,输入:sudo apt-get install git-core ,按下回车之后输入密码即可完成安装: Windows系统在https://git-for- ...

  9. Yeoman 学习笔记

    yoeman 简介:http://www.infoq.com/cn/news/2012/09/yeoman yeoman 官网: http://yeoman.io/ yeoman 是快速创建骨架应用程 ...

  10. JS中给正则表达式加变量

    前不久同事询问我js里面怎么给正则中添加变量的问题,遂写篇博客记录下.   一.字面量 其实当我们定义一个字符串,一个数组,一个对象等等的时候,我们习惯用字面量来定义,例如: var s = &quo ...