C# 多线程中的正确数据访问
我有一个多线程同时使用的方法。这个线程中的每一个都调用另一个方法来从一个列表中接收他们需要的数据(每个线程都应该获得不同的数据,而不是相同的数据) 我编写这段代码是为了从列表中获取数据并在线程中使用它们C# 多线程中的正确数据访问,c#,.net,multithreading,list,C#,.net,Multithreading,List,我有一个多线程同时使用的方法。这个线程中的每一个都调用另一个方法来从一个列表中接收他们需要的数据(每个线程都应该获得不同的数据,而不是相同的数据) 我编写这段代码是为了从列表中获取数据并在线程中使用它们 public static List<string> ownersID; static int idIdx = 0; public static string[] GetUserID() { if (idIdx < ownersID.Count-1) {
public static List<string> ownersID;
static int idIdx = 0;
public static string[] GetUserID()
{
if (idIdx < ownersID.Count-1)
{
string[] ret = { ownersID[idIdx], idIdx.ToString() };
idIdx++;
return ret;
}
else if (idIdx >= ownersID.Count)
{
string[] ret = { "EndOfThat" };
return ret;
}
return new string[0];
}
但有时两个或更多线程可以具有相同的数据。
有什么更好的方法可以做到这一点吗?如果你想使用列表,只需添加一点锁定
private object_lock=new object();
私有列表_List=新列表();
公共void Add(字符串someStr)
{
锁
{
if(_list.Any(s=>s==someStr)//已添加(锁内)
返回;
_添加(someStr);
}
}
删除公共void(字符串someStr)
{
锁
{
if(!\u list.Any(s=>s==someStr)//已删除(锁内)
返回;
_删除(someStr);
}
}
这样,当另一个线程添加/删除任何内容时,任何线程都不会添加/删除任何内容。您的列表将受到保护,不受多线程访问。您可以确保只有一个此类线程。但是,您可以使用ConcurrentDictionary
更新:由于此MSDN线程安全声明,我删除了预锁检查
对列表执行多个读取操作(读取-多线程)是安全的,但是如果在读取集合时修改了集合,则可能会出现问题
在更大规模的应用程序中,您可以使用.Net队列在两个线程之间进行通信。
使用队列的好处是您不需要锁定对象,这将减少延迟。从主线程到线程a、线程B和线程C,数据将通过队列添加和接收。无需锁定。您可以发布a吗?如果您只需要通过递增获得唯一Id,现在很难理解发生了什么-使用
Interlocked
或使用锁定(..)
是,您当前的代码将在多线程模式下发生灾难scenario@T.S.好的,但是,你能给我一个例子吗?我基本上需要从列表中获取一个项目,然后安全地删除该项目(或者如果没有必要,就不删除它)看起来这可能是ConcurrentQueue
的工作,也可能是ConcurrentBag
,但很难判断代码应该实现哪种抽象。具体来说,是对数组第二个元素的硬编码引用(arrOwner[1]
)这是一个不寻常的现象。您的抽象级别可能太低,并且可以从更具体的类中获益,以捕获您正在建模的内容。@Jeroemoster可能-ConcurrentDictionary
bag仍然不能保证唯一性。在列表在另一个区域发生变异时查询列表是不安全的d、 @Servy I更新了答案和。现在,在访问其功能之前,列表将被锁定
string[] arrOwner = GetUserID();
string id = arrOwner[0];
ownersID.RemoveAt(Convert.ToInt32(arrOwner[1]));