讓我們暫時離開平行部,你想要做的是在人員名單上的項目的一些opertaion,你會選擇用於此目的的循環:
for(int i = 0; i < persons.Length, i++)
{
persons[i].Name = "SomeName;
}
或者foreach循環:
foreach(Person person in persons)
{
person.Name = "SomeName";
}
我更喜歡使用foreach循環在這種情況下,因爲我覺得它更適合和明確的,在我的opnion這是一個顯而易見的選擇。
現在讓我們回到並行部分,Parallel.For()應該用於並行執行循環,而Parallel.Foreach()應該用於並行執行foreach循環。
所以如果我們同意在這種情況下foreach循環更合適,那麼我們也應該更喜歡Parallel.Foreach()而不是Parallel.For()。
現在對於你的問題Parallel.Foreach()將採取T的行動作爲參數,所以如果你想一個方法名傳遞給操作一定是因爲Action of T無效的方法是委託給一個void方法這得到類型T的一個參數
所以,使用第一種方法應該工作:
public void UpdatePersonName(Person person)
{
person.Name = "SomeName";
}
和並行部分(使用this過載):
Parallel.Foreach(persons, UpdatePersonName);
另一種選擇,而不是創建seprate方法是使用lambda表達式:
Parallel.Foreach(persons, person => person.Name = "SomeName");
爲了這個原因,你不能使用你的第二個方法:
public Person UpdatePersonName(Person person)
{
person.Name = "SomeName";
return person;
}
內Parallel.Foreach(),因爲它的返回類型不是無效的。
另一個重要的事情,你應該知道,如果你使用的是Parallel.Foreach(),你將需要確保線程安全,並且大多數時候你需要使用某種鎖定來實現這一點。
您應該仔細考慮這一點,因爲有時它不值得花費,在某些情況下foreach loops can run faster than their parallel equivalents。
你需要顯示調用'UpdatePerson'的代碼也是//從緩存和更新屬性線程安全嗎?它可以在沒有問題的情況下從多個線程同時使用嗎?最後,如果'Name'屬性不是自動執行的屬性,則需要向我們顯示。 –
緩存實現不是線程安全的..然而,爲了本次討論的目的,假設我在執行Parallel.for之前已經寫入了緩存,並且沒有更改將被寫入,同時又有什麼關係?從基於唯一標識符的緩存中讀取(知道列表中的所有人都不同)是否有關係?由於一個任務將得到id 1的值..另一個id 2等等(同時,但是不同的id) – ShaneKm