关于并发的那些坑儿

1. 说一些并发编程的那些话

一说到并发,脑子首先冲出来的是啥?复杂,高难度,难调试...

总的来说就是——高逼格(逃:

的确,并发编程的确不是那么简单的事,初级程序员基本上都接触不到并发,更何况是编程了;但是,只要你有心并且耐心学习下去,你就会发现,并发编程也不是遥不可及的!

我在学习并发相关的知识之前,也觉得这些知识好深奥,肯定玩不来的!现在也不这么过来了么,至少面对它不会无从下手。好吧,在展开我下面的问题之前,我先普及一下关于并发的一些基本知识(常识?)

1 概念:并发其实就是同时在做多件事;比如:我左手拿手机的同时,一边回答同事问我的问题! 这是并发;你在有色网站同时下N个种子,这也是并发

2 实施并发的一些方法手段:多线程就是一种并发的手段,很多人认为多线程就是并发,不然,这只是并发的一种手段;还有异步编程,这也是一种手段

平常我们用的最多的当属异步编程了

2. 我遇到的一些麻烦

说完了基本知识,再来说说我遇到的一些问题吧。为了演示明白,主函数代码如下:

DeepCloneObject deepclone = new DeepCloneObject();
AccurateCommon arg = helper.GetAccurateCommon();
Parallel.ForEach(nameValues, dic =>
{
  AccurateCommon argument = (AccurateCommon)deepclone.CopyObject(arg);
  argument.data.coverageList = aq.coverageList;
  ParallelInvokeInterface(handle._uri, dic, argument);
});

 在来看看ParallelInvokeInterface函数:

private void ParallelInvokeInterface(string uri, Insurance insurance, AccurateCommon accCommon) { 
  accCommon.data.insurerCode = insurance.InsuranceCode;
  string response = RealInvokeInterface(uri, accCommon);
  ResponseRefference responseRefference = JsonHelper.Deserializer(response);
  if (responseRefference != null && responseRefference .State == "1") {
    responseRefference.Data.Each(p =>
    {
      if (p.State == "1") {
        string price = "0.00";
        p.CiPremium = p.CiPremium ?? price;
        p.BiPremium = p.BiPremium ?? price;
        p.CarShipTax = p.CarShipTax ?? price;
        m_result.AddOrUpdate(insurance, responseRefference, (str, rrp) => rrp);
      }
    });
  }
}

接下来就是接口调用程序 RealInvokeInterface函数 

private string RealInvokeReferencePriceInterface(string url, AccurateQuotationCommon accqc)
{
  string serializerString = JsonHelper.SerializerObject(accqc);
  return work.Send(url, serializerString);
}

问题在那呢,听我细细说来;

首先,Parallel.ForEach这个API需要注意的点是:因为这个是并行计算,所以切勿数据共享,特别是那些要进行读写的数据,例如我的第一段代码,都要用到一个类型为AccurateCommon变量arg,并且在ParallelInvokeInterface函数中对arg对象的某个属性进行写操作,所以在ForEach执行期间,我必须要保证arg的引用不能相同,所以这里我用深拷贝出另一个对象放进函数执行;而在ParallelInvokeInterface执行期间虽然会对arg进行操作,但是彼此的间是满足互不干扰原则的,那么最后调用接口返回的对象应该不同才对!

但事实却不是,有很少的几率返回的数据还是一样的,所以我也是很疑惑,反复观察我的代码,并没有什么不妥,最后想到了另一种可能性,那就是接口方是不是对这种同时请求接口的情况没有做处理呢?但是这种http请求不就是一次性消费的么,一次请求我发送的数据始终是不同的啊,所以说我的这段代码肯定还是有问题的,得在仔细找找了,如果各位看管发现问题了,望告知,小弟我在此先行谢过

原文地址:https://www.cnblogs.com/ms27946/p/5982022.html