我必须创建一个 WPF UI,它订阅实时 Fx Rate(Currency + rate) 更新并在网格中显示它们(每秒大约 1000 次更新,这意味着网格中的每一行每秒最多可以更新1000次) . 网格在任何时间点都至少有 50 行。
为此,我创建了一个订阅更新事件的 Viewmodel,并将这些更新存储在并发字典中,其中键作为符号,值作为 RateViewModel 对象。然后我有另一个具有所有这些 rateviewmodel 对象的可观察集合,并将其绑定到网格。
代码:
public class MyViewModel
{
private readonly IRatesService ratesService;
private readonly ConcurrentDictionary<string, RateViewModel> rateDictionary;
private object _locker = new object();
public MyViewModel(IRatesService ratesService)
{
this.ratesService = ratesService;
this.ratesService.OnUpdate += OnUpdate;
rateDictionary = new ConcurrentDictionary<string, RateViewModel>();
RateViewModels = new ObservableCollection<RateViewModel>();
}
private void OnUpdate(object sender, RateUpdateEventArgs e)
{
RateViewModel exisistingRate;
if (!rateDictionary.TryGetValue(e.Update.Currency, out exisistingRate))
{
exisistingRate = new RateViewModel(new Rate(e.Update.Currency, e.Update.Rate));
rateDictionary.TryAdd(e.Update.Currency, exisistingRate);
return;
}
lock (_locker)
{
exisistingRate.UpdateRate(e.Update.Rate);
}
Application.Current.Dispatcher.BeginInvoke(new Action(() => SearchAndUpdate(exisistingRate)));
}
public ObservableCollection<RateViewModel> RateViewModels { get; set; }
private void SearchAndUpdate(RateViewModel rateViewModel)
{
//Equals is based on Currency
if (!RateViewModels.Contains(rateViewModel))
{
RateViewModels.Add(rateViewModel);
return;
}
var index = RateViewModels.IndexOf(rateViewModel);
RateViewModels[index] = rateViewModel;
}
}
我对此有4个问题:
有没有办法可以消除 ObservableCollection,因为它会导致 2 个不同的数据结构存储相同的项目 - 但我的更新仍然会转发到 UI?
我使用了并发字典,这会导致锁定整个更新操作。有没有其他聪明的方法来处理这个问题,而不是锁定整个字典或任何数据结构?
我的 UpdateRate 方法也会锁定 - 我在 RateviewModel 上的所有属性都是只读的,除了价格,因为它正在更新。有没有办法让这个原子化,请注意价格是双倍的。
有没有办法可以优化 SearchAndUpdate 方法,这与 1st 有关。目前我认为这是一个 O(n) 操作。
使用.NET 4.0并为了简洁省略了 INPC。
*编辑: *你能帮我以更好的方式重写这个,考虑到所有 4 点吗?伪代码会做。
谢谢,-迈克