亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么循環遍歷時有時候會發生錯誤呢?怎么解決?

為什么循環遍歷時有時候會發生錯誤呢?怎么解決?

C#
蕪湖不蕪 2023-03-03 17:13:12
多線程中訪問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]; //報錯:集合已經被修改 }}
查看完整描述

1 回答

?
慕無忌1623718

TA貢獻1744條經驗 獲得超4個贊

)【異常的原因】

按您給出的代碼,問題出在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 in list)                {                    Console.WriteLine(e.ToString());                }                Console.WriteLine("------------");                Thread.Sleep(1000);            }        }    }     /// <summary>    /// 實體對象    /// </summary>    class Entity    {        public int Id { getset; }        public string Name { getset; }        public string Gender { getset; }        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 in list)                {                    yield return v;                }            }        }        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()        {            return this.GetEnumerator();        }    }}

 


查看完整回答
反對 回復 2023-03-06
  • 1 回答
  • 0 關注
  • 107 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號