多線程中訪問public List<Entity> Entities { get { lock(syncObjecct){return ....}} set{ lock(syncObject){....}}; Entities對(duì)象時(shí),為什么循環(huán)遍歷時(shí)有時(shí)候會(huì)發(fā)生錯(cuò)誤(Note: 我已經(jīng)加鎖對(duì)象并且用for循環(huán)而不是foreach循環(huán)訪問對(duì)象)。我的程序: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(){//多個(gè)線程添加刪除訪問Entities鏈表時(shí)候遍歷有時(shí)會(huì)發(fā)生錯(cuò)誤for (int i = 0; i <Entities.Count;i++) {var item = Entities[0]; //報(bào)錯(cuò):集合已經(jīng)被修改 }}
1 回答

慕無忌1623718
TA貢獻(xiàn)1744條經(jīng)驗(yàn) 獲得超4個(gè)贊
)【異常的原因】
按您給出的代碼,問題出在public List<Entity> Entities{get; set;}上:這個(gè)屬性方法在獲取List<Entity>實(shí)例的執(zhí)行過程中利用了lock(){}來保持同步;但是,一旦這個(gè)屬性方法執(zhí)行結(jié)束就跳出了lock(){}的同步范圍。這意味著:在主函數(shù)中所獲取的List<Entity>實(shí)例已經(jīng)不再受到lock的保護(hù)了!遍歷集合發(fā)生將拋出異常(通常是“集合序數(shù)變化……”之類的異常)
2)【解決方法】
關(guān)鍵是為遍歷集合的方法提供同步功能。見下面的代碼
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) { //啟動(dòng)線程:向集合中添加 Thread threadAdding = new Thread(Adding); threadAdding.IsBackground = true ; threadAdding.Start(); //啟動(dòng)線程:從集合中刪除 Thread threadRemoving = new Thread(Removing); threadRemoving.IsBackground = true ; threadRemoving.Start(); //啟動(dòng)線程:遍歷集合 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> /// 實(shí)體對(duì)象 /// </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> /// 實(shí)體對(duì)象列表(集合) /// </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(); } } } |
- 1 回答
- 0 關(guān)注
- 113 瀏覽
添加回答
舉報(bào)
0/150
提交
取消