鉴于以下内容,最佳同步技术人员是什么
*请注意,这是一个示例模型,还有很多事情要发生。
共享资源是从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包装器并等待它。 像这样的结构:The anser by Stephen Cleary
问题:
1)任何人都可以想到一种更好的方法来同步乐器字典上的操作。
2)在包装WaitHandle的任务中使用async / await有什么好处吗? (如上面链接中描述的那个)
答案 0 :(得分:1)
同步集合的最佳做法
我认为最佳做法是使用lock
,除非您需要其他内容。
例如,如果您需要异步锁定,则可以使用SemaphoreSlim
或其中一个AsyncLock
实现。
或者使用任何类型的任务包装器并等待它。
我不会将该解决方案用于收集同步。如果需要异步兼容同步,请使用异步兼容的同步原语(例如SemaphoreSlim
或AsyncLock
)。如果您不需要它,那么只需使用lock
。
如果 使用基于Task
的对象(例如,它是共享的),则实际上只需要WaitHandle
- 包装器 - WaitHandle
情况在进程之间)并希望使用异步代码来使用它。听起来不像这种情况适用于此。
旁注从字典中读取时我不关心数据集成。这意味着我不介意某个人在任何给定点接收来自字典的非更新值。
无论如何,我建议锁定读取。如果不这样做,可能会出现各种问题(如撕裂)。
正如旁注:您对场景的描述一直使用术语“更新”。听起来您可能需要更多的生产者/消费者解决方案,或者可能需要像Rx这样的发布/订阅,而不是共享的同步集合。