0

我有一些代碼,它需要一個名爲obj的對象列表並將它們轉換爲新對象newobj,並將它們存儲在一個列表中。在Parallel.ForEach循環終止後,所有線程都被終止了嗎?

List<SomeObject> NewListofObjects<SomeObject>(); 
var addListLock = new object(); 

Parallel.ForEach(ListofObjects, obj => 

//Do some operations here on obj to get a newobj 

lock (addListLock) 
{ 
NewListofObjects.Add(newobj);     
} 

); 

if (NewListofObjectsCount == 2) 
{ 
CombineNewObjs(NewListofObjects[0], NewListofObjects[1]); 
} 

該代碼創建新對象並將它們存儲在列表中就好了。但是,當我到達CombineNewObjs(這是Parallel.ForEach循環之外),我得到這個錯誤:「試圖讀取或寫入保護內存這通常是指示其他內存已損壞」。

程序運行正常,如果我在非平行的順序運行它,它正確地做每件事高達CombineNewObjs。難道問題是我必須以某種方式從線程中釋放我的列表,以便我可以在其上執行該方法?

+1

嗨,歡迎!這個問題不同於[你的最後一個](http://stackoverflow.com/q/17416357/634824)?他們看起來幾乎相同。爲了協助我們幫助您,請確保您發佈的代碼能夠編譯。這不是。 –

+0

您好,非常感謝您的光臨!是的,這個問題引用了Parallel.ForEach的結構,詢問在循環終止後是否所有線程都被終止,或者終止後是否必須採取特殊步驟來訪問循環內創建的資源。我之前的問題涉及列表本身是否具有內在線程安全性。 不幸的是我的代碼需要GIS SDK編譯,所以這裏大多數的用戶將無法編譯它沒有安裝必要的軟件。這就是爲什麼我選擇處理簡單的抽象而不是發佈我的實際代碼。 – Conor

+0

請編輯您的問題/標題與您的評論。現在的帖子與上面的評論無關。 –

回答

0

Could the problem be that I have to somehow release my list from threading so that I can execute the method on it?

不,這不是問題。問題可能出現在您未顯示的代碼中。有可能Parallel.ForEach()只是使問題可見。不知道更多關於您的代碼的信息,無法診斷問題。

+0

謝謝!這是我需要的信息。 – Conor

0

列表對象不是線程安全的。使用鎖來保護它在平行的內部是沒有意義的。有線程安全集合,例如blocking collection,但它們具有不同的語義。

+0

使用這樣的鎖是安全的,並且非常合理,假設轉換操作需要很長時間。 – svick

+0

我沒有看到它是兩個列表,我以爲他鎖定在他正在迭代的同一個列表上,如果有兩個列表,這有一些價值,但仍然不是我稱之爲好的習慣用法。創建任務,然後生成添加項目的任務可能是更好的想去 – rerun