C#多线程共享变量循环遍历
多线程中访问publicList<Entity>Entities{get{lock(syncObjecct){return....}}set{lock(syncObjec...
多线程中访问public List<Entity> Entities { get { lock(syncObjecct){return ....}} set{ lock(syncObject){....}}; Entities对象时,为什么循环遍历时有时候会发生错误(Note: 我已经加锁对象并且用for循环而不是foreach循环访问对象)。
我的程序:
private List<Entity> entities = new List<Entities>();
public List<Entity> Entities { get { lock(syncObjecct){return ...entities.}} set{ lock(syncObject){....entities = value}};
private void Insert(Entity entity)
{
Entities.add(entity);
}
private void Remove()
{
if (Entityes.Count >0 )
Entities.Remove(0);
}
int main()
{
//多个线程添加删除访问Entities链表时候遍历有时会发生错误
for (int i = 0; i <Entities.Count;i++)
{
var item = Entities[0]; //报错:集合已经被修改
}
} 展开
我的程序:
private List<Entity> entities = new List<Entities>();
public List<Entity> Entities { get { lock(syncObjecct){return ...entities.}} set{ lock(syncObject){....entities = value}};
private void Insert(Entity entity)
{
Entities.add(entity);
}
private void Remove()
{
if (Entityes.Count >0 )
Entities.Remove(0);
}
int main()
{
//多个线程添加删除访问Entities链表时候遍历有时会发生错误
for (int i = 0; i <Entities.Count;i++)
{
var item = Entities[0]; //报错:集合已经被修改
}
} 展开
1个回答
展开全部
1)【异常的原因】
按您给出的代码,问题出在public List<Entity> Entities{get; set;}上:这个属性方法在获取List<Entity>实例的执行过程中利用了lock(){}来保持同步;但是,一旦这个属性方法执行结束就跳出了lock(){}的同步范围。这意味着:在主函数中所获取的List<Entity>实例已经不再受到lock的保护了!遍历集合发生将抛出异常(通常是“集合序数变化……”之类的异常)
2)【解决方法】
关键是为遍历集合的方法提供同步功能。见下面的代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static EntityList list = new EntityList();
static void Main(string[] args)
{
//启动线程:向集合中添加
Thread threadAdding = new Thread(Adding);
threadAdding.IsBackground = true;
threadAdding.Start();
//启动线程:从集合中删除
Thread threadRemoving = new Thread(Removing);
threadRemoving.IsBackground = true;
threadRemoving.Start();
//启动线程:遍历集合
Thread threadWork = new Thread(Work);
threadWork.IsBackground = true;
threadWork.Start();
Console.ReadKey();
}
static void Adding()
{
int id = 0;
while (true)
{
id++;
list.Insert(new Entity()
{
Id = id,
Gender = "Male",
Name = "Someone" + id.ToString()
});
Thread.Sleep(750);
}
}
static void Removing()
{
while (true)
{
list.Remove();
Thread.Sleep(1000);
}
}
static void Work()
{
while (true)
{
//遍历集合
foreach (var e in list)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("------------");
Thread.Sleep(1000);
}
}
}
/// <summary>
/// 实体对象
/// </summary>
class Entity
{
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public override string ToString()
{
return string.Format(
"Id={0} Name={1} Gender={2}", Id, Name, Gender
);
}
}
/// <summary>
/// 实体对象列表(集合)
/// </summary>
class EntityList : IEnumerable<Entity>
{
object syncObject = new object();
List<Entity> list = new List<Entity>();
public void Insert(Entity entity)
{
lock (syncObject)
{
list.Add(entity);
}
}
public void Remove()
{
lock (syncObject)
{
if (list.Count > 0) list.RemoveAt(0);
}
}
//带同步功能的集合遍历接口
public IEnumerator<Entity> GetEnumerator()
{
lock (syncObject)
{
foreach (var v in list)
{
yield return v;
}
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询