1 System.IndexOutOfRangeException: 在复制内存时检测到可能的 I/O 争用条件。默认情况下,I/O 包不是线程安全的。在多线程应用程序中,必须以线程安全方式(如 TextReader 或 TextWriter 的 Synchronized 方法返回的线程安全包装)访问流。这也适用于 StreamWriter 和 StreamReader 这样的类。 2 在 System.Buffer.InternalBlockCopy(Array src, Int32 srcOffsetBytes, Array dst, Int32 dstOffsetBytes, Int32 byteCount) 3 在 System.IO.StreamWriter.Write(Char[] buffer, Int32 index, Int32 count) 4 在 System.IO.TextWriter.WriteLine(String value) 5 在 System.IO.TextWriter.SyncTextWriter.WriteLine(String value) 6 在 NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd) 7 在 NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session) 8 在 NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) 9 在 NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) 10 在 NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister) 11 --- 内部异常堆栈跟踪的结尾 --- 12 在 NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister) 13 在 NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId) 14 在 NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session) 15 在 NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) 16 在 NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) 17 在 NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType) 18 在 NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType) 19 在 NHibernate.Impl.SessionImpl.Get(String entityName, Object id) 20 在 NHibernate.Impl.SessionImpl.Get(Type entityClass, Object id) 21 在 NHibernate.Impl.SessionImpl.Get[T](Object id) 22 在 Spring.Data.NHibernate.Generic.HibernateTemplate.Execute[T](IHibernateCallback`1 action, Boolean exposeNativeSession) 23 --- 内部异常堆栈跟踪的结尾 --- 24 在 Spring.Data.NHibernate.Generic.HibernateTemplate.Execute[T](IHibernateCallback`1 action, Boolean exposeNativeSession) 25 在 HKTD.PL.EnityNhibrenateDao.GetFromDb[T,TPk](TPk tpk, ConfigPara cp) 26 在 HKTD.PL.EnityNhibrenateDao.GetMem[T,TPk](TPk tpk) 27 在 HKTD.PL.EnityNhibrenateDao.Get[T,TPk](TPk tpk) 28 在 HKTD.CMSMIP.BLL.CmsMipCustomImp.GetAplStrateInHdlLevelAndHdlPersonDep(Nullable`1 HdlLevel, String HdlPersonDep, Int64 ApprovalType, Int64 HdlResponsibleDep) 29 在 CompositionAopProxy_885de1221cf34951a528422d0cdbd902.GetAplStrateInHdlLevelAndHdlPersonDep(Nullable`1 HdlLevel, String HdlPersonDep, Int64 ApprovalType, Int64 HdlResponsibleDep) 30 在 HKTD.CMSMIP.UniSvc.CmsMipServiceCustom.GetAplStrateInHdlLevelAndHdlPersonDep(Nullable`1 HdlLevel, String HdlPersonDep, Int64 ApprovalType, Int64 HdlResponsibleDep) 31 在 HKTD.CMSMIP.UI.Areas.SafeCheck.Models.CheckHdlRecordConvert.InsertRecoTestingAplStrate(CheckHdlRecord checkHdlRecord)
这个问题是发布以后。假如IO 线程报错 那么就会引起IIS 崩溃
看看哪里用到数组,下标溢出了
难道是这里?
@多罗贝勒: 如果strA,没有 "," ,strA.Split(',')[1]就会报错,是不是这里就不知道了
@Yu: 306001,422001;306002,422002;306003,422003;306004,422004;306005,422005;306006,422006;
@多罗贝勒: 最后一个strA为空,肯定报错了
@Yu: if (strA.Split(',')[0] == HdlLevel.Value.ToString()) 空行没有对应上就会跳出去。
刚才我调试了下这里,正常运行,没报错。
这个问题是 正常本地测试什么的都没什么问题。就是发布以后 偶尔会包这个问题。
@Yu: 我看报错的地方是操作IO的时候 。一定是数组吗? 如果是的话那么我就仔细改改数组。
@多罗贝勒: 那这里你可以排除,看看哪里要加lock的,也有可能是运行时间差问题,导致本来下标已经到1,可是还没到,就使用了,具体查代码了
@Yu: 好,谢谢
@多罗贝勒: 查查线程共享数据部分吧,如果有的话
@Yu: 倒是有写日志 的位置。 报错写日志,会不会是 只能单线程写? 同时报错的话就会写不进去
@多罗贝勒: 那你lock一下试试
@Yu: Ok
@Yu: 不行啊,还是报错,能不能帮我看看代码
@Yu:
private readonly object _thislock = new object(); /// <summary> /// /// </summary> /// <param name="HdlLevel"></param> /// <param name="HdlPersonDep">检查人</param> /// <param name="ApprovalType"></param> /// <param name="HdlResponsibleDep"></param> /// <returns></returns> public POCO.SysMang.AplStrate GetAplStrateInHdlLevelAndHdlPersonDep(long? HdlLevel, string HdlPersonDep, long ApprovalType, long HdlResponsibleDep) { lock (_thislock) { long dengji = 0; //获得字典级别对应的关系 string LevelRl = CommonUtils.ConstObj.HdlLevelAndApprovalLevel; string[] LevelStrA = LevelRl.Split(';'); lock (LevelStrA) { foreach (string strA in LevelStrA) { if (HdlLevel != null && strA.Split(',')[0] == HdlLevel.Value.ToString()) { if (strA.Split(',').Length > 1) { bool typ = long.TryParse(strA.Split(',')[1], out dengji); if (!typ) { dengji = CommonUtils.ConstObj.ApprovalLevelC; } } } } } POCO.BaseInfo.DepMang newdep = new DepMang(); if (!string.IsNullOrEmpty(HdlPersonDep)) { string[] HdlPersonDepAll = HdlPersonDep.Split(','); lock (newdep) { if (HdlPersonDepAll.Length == 1) { if (HdlPersonDepAll[0] != null) { newdep = cmsMipBaseObjImp.Get<POCO.BaseInfo.DepMang, long>(Convert.ToInt64(HdlPersonDepAll[0])); } } if (HdlPersonDepAll.Length > 1) { //newdep = GetFunBaseDepMang(depMang); //获得部门中那个最短的部门 IList<POCO.BaseInfo.DepMang> GList = new List<POCO.BaseInfo.DepMang>(); foreach (string var in HdlPersonDepAll) { POCO.BaseInfo.DepMang one = cmsMipBaseObjImp.Get<POCO.BaseInfo.DepMang, long>(Convert.ToInt64(var)); GList.Add(one); } if (GList.Count > 0) { IList<POCO.BaseInfo.DepMang> Alist = GList.OrderByDescending(m => m.DepCode.Length).ToList(); newdep = Alist[0]; } } } lock (newdep) { if (newdep != null) { POCO.SysMang.AplStrate strates = new AplStrate(); if (newdep.EntityDepMangByTopDepId.DepLevel == 113008) { strates = FunJituanAplStrate(dengji, newdep, ApprovalType, HdlResponsibleDep); } else { strates = FunAplStrate(dengji, newdep, ApprovalType, HdlResponsibleDep); } if (strates == null) { string hql = "from AplStrate where "; if (dengji != 0) hql += "ApprovalLevel = " + dengji + " and "; if (newdep.DepLevel == CommonUtils.ConstObj.DepLevelJiTuan) { hql += "ApprovalMain=" + CommonUtils.ConstObj.ApprovalZhuTiJiTuan; } else if (newdep.DepLevel == CommonUtils.ConstObj.DepLevelKuang) { hql += "ApprovalMain=" + CommonUtils.ConstObj.ApprovalZhuTiKuang; } else { POCO.BaseInfo.DepMang topdep = cmsMipDepMangLogic.GetTopDepMang(newdep); if (topdep.DepLevel == CommonUtils.ConstObj.DepLevelJiTuan) hql += "ApprovalMain=" + CommonUtils.ConstObj.ApprovalZhuTiJiTuan; else if (topdep.DepLevel == CommonUtils.ConstObj.DepLevelKuang) hql += "ApprovalMain=" + CommonUtils.ConstObj.ApprovalZhuTiKuang; else hql += "ApprovalMain=" + CommonUtils.ConstObj.ApprovalZhuTiJiTuan; } hql += " and ApprovalType=" + ApprovalType + "and ApprovalDep is null or ApprovalDep=0"; POCO.SysMang.AplStrate aplStrate = cmsMipBaseObjImp.Find<POCO.SysMang.AplStrate>(hql, null); return aplStrate; } else { return strates; } } } } else { string hql = "from AplStrate where ApprovalType=" + ApprovalType; if (dengji != 0) { hql += " and ApprovalLevel = " + dengji + " and "; } if (HdlResponsibleDep == 0) { hql += " and ApprovalDep is null or ApprovalDep=0 "; } else { hql += " and ApprovalDep=" + HdlResponsibleDep; } POCO.SysMang.AplStrate aplStrate = cmsMipBaseObjImp.Find<POCO.SysMang.AplStrate>(hql, null); if (aplStrate == null) { string hqlA = "from AplStrate where ApprovalType=" + ApprovalType; if (dengji != 0) { hqlA += " and ApprovalLevel = " + dengji + " and "; } if (HdlResponsibleDep == 0) { hqlA += " and ApprovalDep is null or ApprovalDep=0 "; } else { POCO.BaseInfo.DepMang HdlResponsibleDepMang = cmsMipBaseObjImp.Get<POCO.BaseInfo.DepMang, long>(HdlResponsibleDep); lock (HdlResponsibleDepMang) { POCO.BaseInfo.DepMang HdlResponsibleTopDep = cmsMipDepMangLogic.GetTopDepMang(HdlResponsibleDepMang); hqlA += " and ApprovalDep=" + HdlResponsibleTopDep.Id; } } return cmsMipBaseObjImp.Find<POCO.SysMang.AplStrate>(hqlA, null); } return aplStrate; } return null; } }
@多罗贝勒: 1.拿掉你最外层lock里面的lock,那些都没用。
2.你最外层的lock只在部分情况下有用,因为这个lock字段是实例的,跟着你当前方法所属的对象实例走的,你如果不同地方new了后lock根本没用。如果不细考虑的话你可以把那个object改为静态的。
3.代码大概看上去像是拼sql去查,这个地方你在拼接的时候未考虑sql注入场景,虽然所有参数都不是字符串类型的,但不够严谨且在大量字符串拼接的时候最好使用stringbuilder
4.你应该把所有的条件拼接都提出来进行封装,每个对象仅负责一个条件,然后最后组合起来组成完成的条件语句。
5.根据你前面的堆栈信息,感觉ISessionImplementor对象并不是线程安全的,你这里是否做了单例?(cmsMipBaseObjImp.Get<POCO.BaseInfo.DepMang, long>(HdlResponsibleDep)
cmsMipBaseObjImp.Find<POCO.SysMang.AplStrate>(hqlA, null)等)
感觉你某个地方用了单例,但由于对象的实例方法非线程安全导致的。
一般解决方案是放弃单例,按需实例化进行操作。如果有其他情况,比如创建对象开销太大(类似连接等),可以使用队列(ConcurrentQueue)来缓存,每次从队列里面获取对象进行操作,如果获取不到则重复尝试。
数组从0开始的,不是从1开始。
检查代码吧。
我看报错的地方是操作IO的时候 。一定是数组吗? 如果是的话那么我就仔细改改数组。
@多罗贝勒: io操作相关的writer一般都不是线程安全的,如果多线程同时进行操作的话会导致其内部的buffer(可以简单理解为一个数组)受不同线程处理最后导致越界。
@Daniel Cai: 能不能帮我看看代码 还是出现这个问题。
private readonly object _thislock = new object(); /// <summary> /// /// </summary> /// <param name="HdlLevel"></param> /// <param name="HdlPersonDep">检查人</param> /// <param name="ApprovalType"></param> /// <param name="HdlResponsibleDep"></param> /// <returns></returns> public POCO.SysMang.AplStrate GetAplStrateInHdlLevelAndHdlPersonDep(long? HdlLevel, string HdlPersonDep, long ApprovalType, long HdlResponsibleDep) { lock (_thislock) { long dengji = 0; //获得字典级别对应的关系 string LevelRl = CommonUtils.ConstObj.HdlLevelAndApprovalLevel; string[] LevelStrA = LevelRl.Split(';'); lock (LevelStrA) { foreach (string strA in LevelStrA) { if (HdlLevel != null && strA.Split(',')[0] == HdlLevel.Value.ToString()) { if (strA.Split(',').Length > 1) { bool typ = long.TryParse(strA.Split(',')[1], out dengji); if (!typ) { dengji = CommonUtils.ConstObj.ApprovalLevelC; } } } } } POCO.BaseInfo.DepMang newdep = new DepMang(); if (!string.IsNullOrEmpty(HdlPersonDep)) { string[] HdlPersonDepAll = HdlPersonDep.Split(','); lock (newdep) { if (HdlPersonDepAll.Length == 1) { if (HdlPersonDepAll[0] != null) { newdep = cmsMipBaseObjImp.Get<POCO.BaseInfo.DepMang, long>(Convert.ToInt64(HdlPersonDepAll[0])); } } if (HdlPersonDepAll.Length > 1) { //newdep = GetFunBaseDepMang(depMang); //获得部门中那个最短的部门 IList<POCO.BaseInfo.DepMang> GList = new List<POCO.BaseInfo.DepMang>(); foreach (string var in HdlPersonDepAll) { POCO.BaseInfo.DepMang one = cmsMipBaseObjImp.Get<POCO.BaseInfo.DepMang, long>(Convert.ToInt64(var)); GList.Add(one); } if (GList.Count > 0) { IList<POCO.BaseInfo.DepMang> Alist = GList.OrderByDescending(m => m.DepCode.Length).ToList(); newdep = Alist[0]; } } } lock (newdep) { if (newdep != null) { POCO.SysMang.AplStrate strates = new AplStrate(); if (newdep.EntityDepMangByTopDepId.DepLevel == 113008) { strates = FunJituanAplStrate(dengji, newdep, ApprovalType, HdlResponsibleDep); } else { strates = FunAplStrate(dengji, newdep, ApprovalType, HdlResponsibleDep); } if (strates == null) { string hql = "from AplStrate where "; if (dengji != 0) hql += "ApprovalLevel = " + dengji + " and "; if (newdep.DepLevel == CommonUtils.ConstObj.DepLevelJiTuan) { hql += "ApprovalMain=" + CommonUtils.ConstObj.ApprovalZhuTiJiTuan; } else if (newdep.DepLevel == CommonUtils.ConstObj.DepLevelKuang) { hql += "ApprovalMain=" + CommonUtils.ConstObj.ApprovalZhuTiKuang; } else { POCO.BaseInfo.DepMang topdep = cmsMipDepMangLogic.GetTopDepMang(newdep); if (topdep.DepLevel == CommonUtils.ConstObj.DepLevelJiTuan) hql += "ApprovalMain=" + CommonUtils.ConstObj.ApprovalZhuTiJiTuan; else if (topdep.DepLevel == CommonUtils.ConstObj.DepLevelKuang) hql += "ApprovalMain=" + CommonUtils.ConstObj.ApprovalZhuTiKuang; else hql += "ApprovalMain=" + CommonUtils.ConstObj.ApprovalZhuTiJiTuan; } hql += " and ApprovalType=" + ApprovalType + "and ApprovalDep is null or ApprovalDep=0"; POCO.SysMang.AplStrate aplStrate = cmsMipBaseObjImp.Find<POCO.SysMang.AplStrate>(hql, null); return aplStrate; } else { return strates; } } } } else { string hql = "from AplStrate where ApprovalType=" + ApprovalType; if (dengji != 0) { hql += " and ApprovalLevel = " + dengji + " and "; } if (HdlResponsibleDep == 0) { hql += " and ApprovalDep is null or ApprovalDep=0 "; } else { hql += " and ApprovalDep=" + HdlResponsibleDep; } POCO.SysMang.AplStrate aplStrate = cmsMipBaseObjImp.Find<POCO.SysMang.AplStrate>(hql, null); if (aplStrate == null) { string hqlA = "from AplStrate where ApprovalType=" + ApprovalType; if (dengji != 0) { hqlA += " and ApprovalLevel = " + dengji + " and "; } if (HdlResponsibleDep == 0) { hqlA += " and ApprovalDep is null or ApprovalDep=0 "; } else { POCO.BaseInfo.DepMang HdlResponsibleDepMang = cmsMipBaseObjImp.Get<POCO.BaseInfo.DepMang, long>(HdlResponsibleDep); lock (HdlResponsibleDepMang) { POCO.BaseInfo.DepMang HdlResponsibleTopDep = cmsMipDepMangLogic.GetTopDepMang(HdlResponsibleDepMang); hqlA += " and ApprovalDep=" + HdlResponsibleTopDep.Id; } } return cmsMipBaseObjImp.Find<POCO.SysMang.AplStrate>(hqlA, null); } return aplStrate; } return null; } }
感觉你在多线程中操作了有下标的对象,而且对该对象的元素有移除类似的操作,检查这种类型的代码吧。
。。。大哥 你写代码碰到数组索引什么的好歹判个长度啊 不能因为自己知道输入就直接给他一个索引下标。万一在生产环境实际输入出现之前没考虑到的情况或是别人不知情调用了 不是各种报错么。。。