c# - 多线程Web服务访问和修改List对象不是线程安全的

标签 c# multithreading

当我的多线程应用程序修改同一个对象并且 List 对象无法处理同时向列表添加对象的两个线程时,我经历了惨痛的教训。

我做了一些研究,发现我可以使用锁来避免这种情况发生,在应用程序顺利运行一个月后,即使锁定对象就位,它也会再次发生。我不明白怎么还会发生这种情况。 错误消息与之前相同: 1-源数组不够长。检查 srcIndex 和长度,以及数组的下限。 2-索引超出了数组的范围。

在类私有(private)成员中我有这个成员变量

private static readonly object _syncLock = new object();

在公共(public)职能

public Dictionary<int, QueuedLetter> GetXMLFragment(Dictionary<int, QueuedLetter> queuedLetters, GroupNode GroupNode, GroupNode ParentGroupNode, StoredProcedure storedProcedure)

这是我使用_synclock对象的地方,代码行如下

XmlFragment xf = new XmlFragment();
xf.Fragment = xe;
xf.LetterQueueOID = lq.LetterQueueOID;
xf.ParentGroupNodeName = ParentGroupNodeName;
xf.LinkingField = GroupNode.LinkingField;
xf.GroupNodeName = GroupNode.GroupNodeName;

lock (_syncLock)
{
   if (lq.Fragments == null)
      lq.Fragments = new List<XmlFragment>();
   lq.Fragments.Add(xf);
}

我使用线程池在另一个类中创建多线程功能,它调用与上面发生锁定的类相同的类中的启动函数

events[i] = new AutoResetEvent(false);
AttachFragments f = new AttachFragments(events[i], groupNodeOID, QueuedLetters, string.Format("Failed while fragment Data : {0}, was executing ", groupNodeName));
f.OnException += ThreadErroredOut;
ThreadPool.QueueUserWorkItem(new WaitCallback(f.UpdateFragments));

如果您能给我一些关于我做错的地方的建议,我将不胜感激。

我考虑过使用 .NET 4.0 中的线程安全集合 http://msdn.microsoft.com/en-us/library/dd997305.aspx 但我还没有使用过它,如果我将其更改为这样,这将导致代码发生重大变化,这将需要由 Q.A 进行更深入的测试。团队。

两个异常的堆栈跟踪: 1-源数组不够长。检查 srcIndex 和长度,以及数组的下限: 在System.Array.Copy(数组sourceArray,Int32 sourceIndex,数组destinationArray,Int32 destinationIndex,Int32长度, bool 可靠)在System.Collections.Generic.List1.Insert(Int32索引,T项)在JE.ThunderHead C:\TFS\LMS\Release\LM_05\LM_05.01\Solutions\ThunderHead\JE.Thunderhead.Business\中的.Business.AttachFragments.GetXMLFragment(字典2queuedLetters、GroupNode GroupNode、GroupNode ParentGroupNode、StoredProcedure storageProcedure) AttachFragments.cs:位于 C:\TFS\LMS\Release\LM_05\LM_05.01\Solutions\ThunderHead\JE.Thunderhead.Business\AttachFragments.cs 中 JE.ThunderHead.Business.AttachFragments.UpdateFragments(Object stateinfo) 的第 135 行:第99行

2- 索引超出了数组范围: 在 System.Collections.Generic.List1.Add(T item) 在 JE.ThunderHead.Business.AttachFragments.GetXMLFragment(Dictionary2 queuedLetters, GroupNode GroupNode, GroupNode ParentGroupNode, StoredProcedure storeProcedure) 在 C:\TFS\LMS\Release\LM_05\LM_05.01\Solutions\ThunderHead\JE.Thunderhead.Business\AttachFragments.cs:第 231 行

最佳答案

从您发布的堆栈跟踪来看,该列表上似乎有一个 Insert,但您未在此处显示。如果是这种情况,您需要使用相同的锁定对象来锁定该 Insert

关于c# - 多线程Web服务访问和修改List对象不是线程安全的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7193047/

相关文章:

c# - 在 C# 中启动应用程序的 linux 服务,该应用程序从 tcp 端口读取并启动 GTK 窗口

c# - SlSvcUtil.exe 底层连接被关闭 : Could not establish trust relationship for the SSL/TSL secure channel

c# - 使用 C# 驱动程序按名称打开 MongoDB GridFS

c# - 在另一个线程上创建表单的地方使用 ShowDialog(form)?

java - 如何杀死在线程中运行的 Runnable?

c# - ASP.NET 文件上传在 Windows Azure 中不起作用

c# - EF6 - 运行不带种子的更新数据库命令

java - 根据某些参数获取对另一个线程的引用

c# - 在 C# 线程中传递参数化方法时出错

java - 似乎我的接收方法没有在 java 中的多播套接字上获取数据包