2011年6月1日 星期三

[LINQ] 集合已修改; 列舉作業可能尚未執行??

今天同事在寫程式遇到這問題.....

問我.... LINQ 可以在 multi-thread 環境下執行嗎?? 程式起來一直有問題......

我心裡想......怎麼會不行? 如果不行,微軟不就搞了一個大飛機了..........?

後來發現其實跟 LINQ 無關,而是在進行列舉作業時不能去修改集合的值

先來看看可以正常運作的程式:

重點有兩個部份:

1. 第 56~59 行,要修改進行列舉工作中的集合資料,必須先將 key 集合複製出來再進行修改,直接修改事不行的.....

2. 第 44 行,此處透過 ToArray() 方式將 value 集合複製一份出來,並針對複製的集合選取其 max value,若是將 ToArray() 拿掉,跑一段時間就會出現"集合已修改; 列舉作業可能尚未執行"的錯誤.....因為有另外一個執行緒正在進行集合內容的修改,而 Max() 這個 method 也應該是使用列舉方式達成的.....


2011/07/15 更新:

使用 System.Collections.Concurrent namespace 中的 thread safe 集合物件就可以解決這個問題了.....

1 則留言:

  1. 集合已修改這個問題也常常發生在我的程式當中~~不過我是在foreach取每個值的過程當中,另一個執行序又去存取裡面的內容,對我程式來說是有點難以控制的部份
    最後我寫了一個flag去擋程式碼存取的動作~~

    回覆刪除