[英]C# Best practice for synchronizing a collection
鑒於以下情況,最好的同步技術是什么
* 請注意,這是一個示例模型,還有更多事情要做。
共享資源是從 2 個地方更新的儀器字典:
(1) 一個內部值正在快速更新。
(2)整個集合被刷新。
public class Insturment
{
public Feed Feed{ get; set;}
}
static IDictionary<string,Instrument> instruments = new Dictionary<string,Instrument>();
// (1) This happens frequently
public void OnNewFeed(Feed feed)
{
instruments[feed.Symbol].Feed = feed;
}
// (2) happens every few hours ,or manually triggered at any given time
public void BuildInstruments()
{
foreach(var instrument in newInstruments)
{
instruments.AddOrUpdate(insturment.Symbol,insturment);
}
}
當使用手動重置事件重建整個集合時,我想到了 UpdateFeed() 上相同的基本概念塊線程。
ManualResetEvent _mre = new ManualResetEvent(false);
public void OnNewFeed(Feed feed)
{
_mre.WaitOne();
instruments[feed.Symbol].Feed = feed;
}
public void BuildInstruments()
{
_mre.Reset();
foreach(var instrument in newInstruments)
{
instruments.AddOrUpdate(insturment.Symbol,insturment);
}
_mre.Set();
}
或者使用任何類型的 Task 包裝器並等待它。 類似這樣的結構: Stephen Cleary 的 anser
問題 :
1)任何人都可以想到一種更好的方法來同步儀器字典上的操作。
2) 在包裝 WaitHandle 的任務上使用 async/await 有什么好處嗎? (就像上面鏈接中描述的那樣)
同步集合的最佳實踐
我會說最好的做法是使用lock
除非你需要別的東西。
例如,如果您需要異步鎖定,您可以使用SemaphoreSlim
或AsyncLock
實現之一。
或者使用任何類型的 Task 包裝器並等待它。
我不會使用該解決方案進行集合同步。 如果您需要異步兼容的同步,則使用異步兼容的同步原語(例如SemaphoreSlim
或AsyncLock
)。 如果您不需要它,那么只需使用lock
。
只有當您必須使用基於WaitHandle
的對象(例如,它在進程之間共享)並希望通過異步代碼使用它時,才需要Task
-wrapper-around- WaitHandle
情況。 聽起來這種情況在這里不適用。
旁注我不關心從字典中閱讀時的數據完整性。 這意味着我不介意有人在任何給定點從字典中接收未更新的值。
無論如何,我確實建議鎖定讀取。 如果您不這樣做,可能會出現各種問題(例如撕裂)。
順便提一下:您對場景的描述一直使用“更新”一詞。 聽起來您可能想要更多的生產者/消費者解決方案,或者可能需要像 Rx 這樣的發布/訂閱,而不是共享的、同步的集合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.