2013-07-20 21 views
0

我想在這裏揭穿不可變集合。我的攻擊點是經典的pub-sub事件經紀人,我們維持訂閱的ImmutableHashSet<Subscription>如果我在枚舉ImmutableHashSet的同時覆蓋它會發生什麼?

一個訂閱,然後操作會做

var s = new Subscription(this, subscriber); 
subscriptions = subscriptions.Add(s); 

和發佈操作會做類似

foreach (var s in subscriptions) 
    s.Subscriber.OnNext(args); 

然而,讓我們假設假設,雖然發佈操作正在發生的事情,有人贊同,變量subscriptions被取代。 foreach循環會正常工作,還是會被徹底壞掉? (如果是這樣,有什麼辦法解決這個問題?)謝謝。

回答

6

該變量subscriptions只讀取開始的循環。請記住,foreach被翻譯你的代碼是這樣的:

using (var iterator = subscriptions.GetEnumerator()) 
{ 
    while (iterator.MoveNext()) 
    { 
     var s = iterator.Current; 
     s.Subscriber.OnNext(args); 
    } 
} 

所以基本上,改變subscriptions變量的值,你叫GetEnumerator()不會影響行爲的休息畢竟 - 它只會影響它下一個時間。 (假設相關的內存屏障已到位等)

+0

謝謝!如果對其執行的_only_操作是覆蓋操作,是否需要擔心多線程訪問「訂閱」?這可以被認爲是原子的,對吧? –

+0

@DmitriNesteruk:它是原子的,但這不像波動。你永遠不會看到一個無效的參考 - 但你可能看不到最近寫入的值。考慮使用「互鎖」或鎖。 –

+0

而不是使用'ImmutableInterlocked'會有意義嗎? –

相關問題