我有一个在多线程应用程序中使用的共享C#public static List<long>
。
在登录后,检查用户的“ID”(这是一个独特的'长' 执行以确定它是否包含在此共享列表中,如果没有,则用户的ID将添加到此共享列表。
在注销后,此用户的ID将从共享列表中删除(假设在删除之前检查用户的ID是否在列表中)。用户无权访问其ID。
问题:是否有锁访问上述场景中所需的共享列表对象?如果是这样,执行的哪个序列将导致意外数据?
Byrd要求代码。以下是一些反映上述问题/场景的通用代码:
public class MyApp
{
public static readonly object _userIDs = new object();
}
void Login(long uniqueUserID)
{
if (_userIDs.Contains(uniqueUserID) == false)
{
_userIDs.Add(uniqueUserID);
}
}
void LogOut(long uniqueUserID)
{
if (_userIDs.Contains(uniqueUserID) == true)
{
_userIDs.Remove(uniqueUserID);
}
}
答案 0 :(得分:0)
在访问同一列表的多线程应用程序中,除非先将其锁定,否则这可能是灾难性的。
当你在没有线程的情况下迭代列表时,你不能这样做。
List<object> dataList = new List<object>(){"foo","bar","my","list"}
foreach(object o in dataList){
dataList.Remove(o);
}
不确定确切的错误是什么,但是,当您迭代它时,您正在更改正在迭代的对象的值。它会崩溃。
如果您将其添加到“以后删除”列表中,那么让线程删除之后应该没问题的数据。像这样......
List<object> dataList = new List<object>(){"foo","bar","my","list"};
List<object> toRemoveLater = new List<object>();
foreach(object o in dataList){
toRemoveLater.Add(o);
}
foreach(object o in toRemoveLater ){
dataList.Remove(o);
}
在多线程应用程序中,虽然您很可能会遇到并发修改错误,因为您正在更改内存中的值而另一个线程正在迭代它。
但是,有一些线程安全列表会强制其他线程轮流等待内存。这取决于你正在做什么,看到你的代码可能会有所帮助。