2016-10-03 67 views
-1

假設我有一個「獨特」的人員列表,我需要更新。我想用的Parallel.For()Parallel.For()更新項目的屬性

方法問題:

public void UpdatePerson(Person row){ 
    row.Name = //get from cache and update property 
} 

VS

public Person UpdatePerson(Person row){ 
    row.Name = //get from cache and update property 
    return row; 
} 

使用的Parallel.For()來枚舉該列表和並行運行這些更新(即調用這個方法),使用一個和另一個是否存在任何潛在的問題?

+1

你需要顯示調用'UpdatePerson'的代碼也是//從緩存和更新屬性線程安全嗎?它可以在沒有問題的情況下從多個線程同時使用嗎?最後,如果'Name'屬性不是自動執行的屬性,則需要向我們顯示。 –

+0

緩存實現不是線程安全的..然而,爲了本次討論的目的,假設我在執行Parallel.for之前已經寫入了緩存,並且沒有更改將被寫入,同時又有什麼關係?從基於唯一標識符的緩存中讀取(知道列表中的所有人都不同)是否有關係?由於一個任務將得到id 1的值..另一個id 2等等(同時,但是不同的id) – ShaneKm

回答

1

讓我們暫時離開平行部,你想要做的是在人員名單上的項目的一些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

-2

無論你的返回對象是什麼。根據執行方法的不同,Parallel.For()將運行相同的操作。如果您等待Person返回使用它,那麼它不會減慢應用程序的速度,因爲它在更新完成之前不會返回Person對象。

如果返回值是無效的,那麼應用程序的某些其他部分不會等待返回值,理論上應該運行得很好,無論何時發生更新。

相關問題