/// <summary> /// Generate and publish a set of quotes. /// </summary> private void GenerateAndPublishQuotes() { // get indexes of symbols we'll pick - quickly acquire lock on _subscribedSymbols list // and make a clone of it by adding to a new list. Then we can release that lock. List<string> clonedSubscribedSymbolsList = new List<string>(); lock (_symbolsLock) { clonedSubscribedSymbolsList.AddRange(_subscribedSymbols); } List<string> symbolsToPick = new List<string>(); for (int i = 0; i < clonedSubscribedSymbolsList.Count; i++) { int pick = rand.Next(0, 2); if (pick == 1) { symbolsToPick.Add(clonedSubscribedSymbolsList[i]); } } // for each symbol, get it's last price and it's price enumerator from their dictionaries // and use them to generate a new quote for the symbol. foreach (var symbol in symbolsToPick) { IEnumerator<double> priceEnumerator; lock (_enumeratorsLock) // lock here to make sure that a subscribed thread isn't adding an enumerator to the list while we are retrieving. { priceEnumerator = _symbolToPriceEnumerator[symbol]; } double lastPrice = priceEnumerator.Current; priceEnumerator.MoveNext(); double newPrice = priceEnumerator.Current; int volume = rand.Next(1, 10) * 50; DateTime date = DateTime.Now; Tick tick; if (newPrice < lastPrice) tick = Tick.Down; else if (newPrice > lastPrice) tick = Tick.Up; else tick = Tick.NoChange; Quote newQuote = new Quote(symbol, newPrice, volume, date, tick); QuoteArrived(newQuote); } }
/// <summary> /// If there are subscribers to the QuoteArrived /// event, then notify them. /// </summary> /// <param name="quote"></param> protected virtual void OnQuoteArrived(Quote quote) { if (QuoteArrived != null) QuoteArrived(quote); }
void _source_QuoteArrived(Quote obj) { Action dispatchAction = () => Quotes.Insert(0, obj); _currentDispatcher.BeginInvoke(dispatchAction); }