我必須創建一個WPF用戶界面,用於實時Fx Rate(貨幣+費率)更新並將其顯示在網格中(每秒大約1000次更新,這意味着網格中的每一行都可以獲得更新upto每秒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,因爲它導致了兩種不同的數據結構存儲相同的項目 - 但仍然有我的更新中繼到用戶界面?
我已經使用了Concurrent Dictionary,它會導致鎖定整個更新操作。有沒有其他聰明的方式來處理這個問題,而不是鎖定整個dicitionary或任何數據結構?
我的UpdateRate方法也鎖 - 我的RateviewModel上的所有屬性都是隻讀的,除了價格以外,因爲它正在更新。有沒有辦法使這個原子,請注意,價格是雙倍。
有沒有一種方法可以優化SearchAndUpdate方法,這與第一種有關。目前我相信這是一個O(n)操作。
使用.NET 4.0和省略INPC爲簡潔。
* 編輯: *請您幫助我以更好的方式重寫這一點,並將所有4點考慮在內? Psuedocode會做。
感謝, -Mike
你可以發佈一些點3的僞代碼嗎? – Mike
我不是很清楚這個「使用Interlocked.CompareExchange設置專用字段爲1,如果這返回1退出,因爲仍然有一個未決的UI更新 如果Interlocked.CompareExchange返回0,調用到UI並激發您的屬性更改了事件並將您的限制字段更新爲0(技術上,如果您關心的不是x86,則需要執行更多操作)「---您可以發佈一個簡短的代碼段嗎? – Mike
@Mike我添加了代碼來顯示技術 – Yaur