首頁 » C#開發 » [C#] Foreach時發生”集合已修改; 列舉作業可能尚未執行”

[C#] Foreach時發生”集合已修改; 列舉作業可能尚未執行”

作者:

分類:

最近在寫多執行緒的功能有需要用到物件池(object pool)的架構,當然最簡單的想法就是用List<T>搭配LINQ解決。

但測試的時候,偶爾Log會報”集合已修改; 列舉作業可能尚未執行”,第一次看到這段文字有點一頭霧水。

public void Test()
{
    foreach (var item in list.Where(x => x.Name == target))
    {
        //DoSomething...
    }
}

多方了解後才知道是在foreach的過程中list被其他執行緒修改導致報錯。

有個簡單的解決方法是在foreach的最後加上ToList(),讓本次foreach時先拷貝一份列表,但內容仍是相同的參考。

只是對已經被pool移除的物件,可能會有例外發生(ex.移除過程被呼叫dispose())的風險。

public void Test()
{
    foreach (var item in list.Where(x => x.Name == target).ToList())
    {
        //DoSomething...
    }
}

如果有移除物件的動作,可以將原本的List<T>改成ConcurrentBag<T>或是及其他執行緒安全的結構(偉哉.NET),在物件的存取過程中保證物件的生命週期。

參考資料

「cian」的個人頭像

留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *