﻿<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/css' href='https://stocksharp.ru/css/style.css'?>
<?xml-stylesheet type='text/css' href='https://stocksharp.ru/css/bbeditor.css'?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html">GuiDispatcher.AddPeriodicalAction</title>
  <id>~/topic/3289/guidispatcher_addperiodicalaction/</id>
  <rights type="text">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  <updated>2026-04-05T23:58:12Z</updated>
  <logo>https://stocksharp.ru/images/logo.png</logo>
  <link href="https://stocksharp.ru/handlers/atom.ashx?category=topic&amp;id=3289" rel="self" type="application/rss+xml" />
  <entry>
    <id>https://stocksharp.ru/posts/m/23347/</id>
    <title type="text">Понятно, то есть одним словом в примере немного мудрено реализован механизм?</title>
    <published>2013-01-12T22:36:31Z</published>
    <updated>2013-01-12T22:36:31Z</updated>
    <author>
      <name>FlashPlayer</name>
      <uri>https://stocksharp.ru/users/16669/</uri>
      <email>info@stocksharp.ru</email>
    </author>
    <content type="html">Понятно, то есть одним словом в примере немного мудрено реализован механизм?</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.ru/posts/m/23345/</id>
    <title type="text">Ведь теперь получается совершенно запутанная последовательность действия, как я понимаю. Вот у нас е...</title>
    <published>2013-01-12T13:34:16Z</published>
    <updated>2013-01-12T13:34:16Z</updated>
    <author>
      <name>Геннадий Ванин (Gennady Vanin)</name>
      <uri>https://stocksharp.ru/users/6413/</uri>
      <email>info@stocksharp.ru</email>
    </author>
    <content type="html">&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;FlashPlayer &lt;a href="https://stocksharp.ru/posts/m/23338/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;Ведь теперь получается совершенно запутанная последовательность действия, как я понимаю. Вот у нас есть два словаря, пока что пустых. Пользователь кликает по кнопке создать стакан и в словарь _quotesWindows добавляется элемент А = (Security, QuotesWindow). По идее, следуя из того, что словари синхронизированы (хотя я до сих пор не понимаю, как это осуществляется, где и кем) в словаре _changedDepths появляется элемент В = (MarketDepth, QuotesWindow). Причем А и В имеют одно и тоже значение,а ключи разные, хотя и соответствуют одному и тому же инструменту.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Ну, дак в соответствии с Вами же процитированным кодом:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;
private void TraderOnMarketDepthsChanged(IEnumerable&amp;lt;MarketDepth&amp;gt; depths)
{
    foreach (var depth in depths)
    {
         var wnd = _quotesWindows.TryGetValue(depth.Security);

         if (wnd != null)
         _changedDepths[depth] = wnd;
}
}&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt; &lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;FlashPlayer &lt;a href="https://stocksharp.ru/posts/m/23338/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;Далее в TraderOnMarketDepthsChanged по каждому обновленному MarketDepth делается что-то невероятное&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Это не далее, уже проехали выше&lt;br /&gt;&lt;br /&gt;&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;FlashPlayer &lt;a href="https://stocksharp.ru/posts/m/23338/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;Ведь можно, как вы сказали выше, вести только один словарь _changedDepths и в событии TraderOnMarketDepthsChanged делать то, что делается в _dispatcher.AddPeriodicalAction и результат по идее дб тот же&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Делайте&lt;br /&gt;Если бы мне нужно было бы, я бы сделал</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.ru/posts/m/23338/</id>
    <title type="text">Хм, спасибо снова за такие пояснения. Не все понятно в середине, но важен итог - получается AddPerio...</title>
    <published>2013-01-11T20:06:08Z</published>
    <updated>2013-01-11T20:06:08Z</updated>
    <author>
      <name>FlashPlayer</name>
      <uri>https://stocksharp.ru/users/16669/</uri>
      <email>info@stocksharp.ru</email>
    </author>
    <content type="html">Хм, спасибо снова за такие пояснения. Не все понятно в середине, но важен итог - получается AddPeriodicalAction вызывается каждые 10мс? Тогда остается открытой эта часть моего вопроса:&lt;br /&gt;&lt;br /&gt;&amp;quot;&lt;br /&gt;Ведь теперь получается совершенно запутанная последовательность действия, как я понимаю. Вот у нас есть два словаря, пока что пустых. Пользователь кликает по кнопке создать стакан и в словарь _quotesWindows добавляется элемент А = (Security, QuotesWindow). По идее, следуя из того, что словари синхронизированы (хотя я до сих пор не понимаю, как это осуществляется, где и кем) в словаре _changedDepths появляется элемент В = (MarketDepth, QuotesWindow). Причем А и В имеют одно и тоже значение,а ключи разные, хотя и соответствуют одному и тому же инструменту. Далее в TraderOnMarketDepthsChanged по каждому обновленному MarketDepth делается что-то невероятное: ищется соответствующий ему элемент в _quotesWindows и соответствующий ему элемент в _changedDepths, после этого QuotesWindow из первого присваивается второму. Зачем?!Вот этот момент мне не понятен. Далее, как раз с помощью диспатчера (что мне тоже непонятно, но выше я уже это спросил) в _changedDepths во всех элементах берутся котировки из ключа и пихаются в значение. Таким образом мы наконец-то получаем обновленный QuotesWindow (то есть в стакане нашем, наконец-то появляются обновленные котировки). Но это же адово сложный процесс. &lt;br /&gt;&lt;br /&gt;Ведь можно, как вы сказали выше, вести только один словарь _changedDepths, и в событии TraderOnMarketDepthsChanged делать то, что делается в _dispatcher.AddPeriodicalAction и результат по идее дб тот же. Или нет? Спасибо заранее за пояснения. А то оч уж сложная механика, для вроде кажущихся несложный действий.&lt;br /&gt;&amp;quot;&lt;br /&gt;&lt;br /&gt;И к тому же добавляется еще один - а не накладно каждые 10мс вызывать обновление всего списка котировок, вместо того, чтобы обновлять его по событию? </content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.ru/posts/m/23337/</id>
    <title type="text">Как я понимаю, что тут происходит: AddPeriodicalAction, как следует из названия, вызывает с какой-то...</title>
    <published>2013-01-11T19:38:24Z</published>
    <updated>2013-01-11T19:38:24Z</updated>
    <author>
      <name>Moadip</name>
      <uri>https://stocksharp.ru/users/5973/</uri>
      <email>info@stocksharp.ru</email>
    </author>
    <content type="html">&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;Цитата:&lt;/span&gt;&lt;div class="innerquote"&gt;Как я понимаю, что тут происходит: AddPeriodicalAction, как следует из названия, вызывает с какой-то (с какой???) периодичностью нижеидущее действие, которое, в свою очередь, заполняет QuotesWindow из MarketDepth. Как же все таки истинно работает этот диспатчер - в чем его обязанность, удобство перед таймером или вообще необходимость?&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Библиотека &lt;b&gt;Ecng.Xaml&lt;/b&gt; не обфусцирована. &lt;br /&gt;И когда возникают вопросы как же оно там все внутри устроено, можно открыть и посмотреть код Reflector или R#. Как бесплатная альтернатива dotPeek.&lt;br /&gt;&lt;br /&gt;Открываем, смотрим:&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;

    public void AddPeriodicalAction(Action action)
    {
      if (action == null)
        throw new ArgumentNullException(&amp;quot;action&amp;quot;);
      this._periodicalActions.Add(action);
      this.StartTimer();
    }
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Переходим по &lt;b&gt;StartTimer&lt;/b&gt;:&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;

    private void StartTimer()
    {
      this._lastTime = DateTime.Now;
      lock (this._lock)
      {
        if (this._timer != null)
          return;
        this._timer = new DispatcherTimer(DispatcherPriority.Normal, this.Dispatcher);
        this._timer.Tick += new EventHandler(this.OnTimerTick);
        this._timer.Interval = new TimeSpan(this.Interval.Ticks / 10L);
        this._timer.Start();
      }
    }
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Видим создание объекта типа &lt;b&gt;DispatcherTimer&lt;/b&gt;. Полное имя - &lt;b&gt;System.Windows.Threading.DispatcherTimer&lt;/b&gt;, что это за класс можно почитать на MSDN.&lt;br /&gt;Дальше интересна строчка:&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;

this._timer.Interval = new TimeSpan(this.Interval.Ticks / 10L);
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Точнее &lt;b&gt;this.Interval.Ticks&lt;/b&gt;. Переходим по &lt;b&gt;Interval&lt;/b&gt; и видим следующее:&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;

    public TimeSpan Interval
    {
      get
      {
        return this._interval;
      }
      set
      {
        if (value &amp;lt;= TimeSpan.Zero)
          throw new ArgumentOutOfRangeException(&amp;quot;value&amp;quot;);
        this._interval = value;
        this.StopTimer();
        this.StartTimer();
      }
    }
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;И последний переход по _&lt;b&gt;interval&lt;/b&gt;, в то место где данное поле инициализируется:&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;

private TimeSpan _interval = TimeSpan.FromMilliseconds(100.0);
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;В итоге по умолчания &lt;b&gt;AddPeriodicalAction &lt;/b&gt; работает с периодичностью = TimeSpan.FromMilliseconds(100.0).Ticks / 10L.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.ru/posts/m/23328/</id>
    <title type="text"> Насколько я понимаю, котировки дублируются в 2х словарях и при их обновлении их надо скопировать (с...</title>
    <published>2013-01-11T14:50:45Z</published>
    <updated>2013-01-11T14:50:45Z</updated>
    <author>
      <name>FlashPlayer</name>
      <uri>https://stocksharp.ru/users/16669/</uri>
      <email>info@stocksharp.ru</email>
    </author>
    <content type="html">&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;Геннадий Ванин (Gennady Vanin) &lt;a href="https://stocksharp.ru/posts/m/23313/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;[quote=FlashPlayer;23289]&lt;br /&gt;&lt;br /&gt;Насколько я понимаю, котировки дублируются в 2х словарях и при их обновлении их надо скопировать (синхронизировать) из одного в другой &lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Вот тут тоже спорно и непонятно, ведь именно в TraderOnMarketDepthsChanged никакого обновления ни одной котировки не происходит - тут то и беда. Оно происходит только в диспатчере этом. И вот такая запутанность непонятна. В TraderOnMarketDepthsChanged только копирование по ссылке значений происходит (опять же непонятно зачем). Короче совсем каша какая-то.</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.ru/posts/m/23327/</id>
    <title type="text">Огромное спасибо за такой развернутый ответ. Все практически встало на свои места. Остался один вопр...</title>
    <published>2013-01-11T14:43:26Z</published>
    <updated>2013-01-11T14:43:26Z</updated>
    <author>
      <name>FlashPlayer</name>
      <uri>https://stocksharp.ru/users/16669/</uri>
      <email>info@stocksharp.ru</email>
    </author>
    <content type="html">Огромное спасибо за такой развернутый ответ. Все практически встало на свои места. Остался один вопрос по теме - как все таки работает &amp;quot;синхронизация&amp;quot; мд этими двумя словарями? Вот мы их проинициализировали - два словаря с одинаковыми значениями, но разными ключами. Неужели этого достаточно для того, чтобы если в одном словаре появился новый элемент, то он появился и в другом? Я честно гуглил,но так и не понял как работает этот класс. &lt;br /&gt;&lt;br /&gt;И есть еще один вопрос, который связан с моими непониманием некоторых особенностей языка. Помогите пожалуйста также наглядно разобраться с объектом класса GuiDispatcher : _dispatcher. Вот в том же примере в том же классе SecuritiesWindow встречается такой код:&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:plain"&gt;

_dispatcher.AddPeriodicalAction(() =&amp;gt;
			{
				foreach (var pair in _changedDepths.SyncGet(s =&amp;gt; s.CopyAndClear()))
				{
					pair.Value.Quotes.Clear();
					pair.Value.Quotes.AddRange(pair.Key.SyncGet(md =&amp;gt; md.Clone().Reverse()));
				}
			});
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Как я понимаю, что тут происходит: AddPeriodicalAction, как следует из названия, вызывает с какой-то (с какой???) периодичностью нижеидущее действие, которое, в свою очередь, заполняет QuotesWindow из MarketDepth. Как же все таки истинно работает этот диспатчер - в чем его обязанность, удобство перед таймером или вообще необходимость?&lt;br /&gt;&lt;br /&gt;Ведь теперь получается совершенно запутанная последовательность действия, как я понимаю. Вот у нас есть два словаря, пока что пустых. Пользователь кликает по кнопке создать стакан и в словарь _quotesWindows добавляется элемент А = (Security, QuotesWindow). По идее, следуя из того, что словари синхронизированы (хотя я до сих пор не понимаю, как это осуществляется, где и кем) в словаре _changedDepths появляется элемент В = (MarketDepth, QuotesWindow). Причем А и В имеют одно и тоже значение,а ключи разные, хотя и соответствуют одному и тому же инструменту. Далее в TraderOnMarketDepthsChanged по каждому обновленному MarketDepth делается что-то невероятное: ищется соответствующий ему элемент в _quotesWindows и соответствующий ему элемент в _changedDepths, после этого QuotesWindow из первого присваивается второму. Зачем?!Вот этот момент мне не понятен. Далее, как раз с помощью диспатчера (что мне тоже непонятно, но выше я уже это спросил) в _changedDepths во всех элементах берутся котировки из ключа и пихаются в значение. Таким образом мы наконец-то получаем обновленный QuotesWindow (то есть в стакане нашем, наконец-то появляются обновленные котировки). Но это же адово сложный процесс. &lt;br /&gt;&lt;br /&gt;Ведь можно, как вы сказали выше, вести только один словарь _changedDepths, и в событии TraderOnMarketDepthsChanged делать то, что делается в _dispatcher.AddPeriodicalAction и результат по идее дб тот же. Или нет? Спасибо заранее за пояснения. А то оч уж сложная механика, для вроде кажущихся несложный действий.</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.ru/posts/m/23313/</id>
    <title type="text"> private readonly SynchronizedDictionary _quotesWindows = new SynchronizedDictionary(); private read...</title>
    <published>2013-01-11T12:28:55Z</published>
    <updated>2013-01-11T12:40:21Z</updated>
    <author>
      <name>Геннадий Ванин (Gennady Vanin)</name>
      <uri>https://stocksharp.ru/users/6413/</uri>
      <email>info@stocksharp.ru</email>
    </author>
    <content type="html">&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;FlashPlayer &lt;a href="https://stocksharp.ru/posts/m/23289/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;
private readonly SynchronizedDictionary&amp;lt;Security, QuotesWindow&amp;gt; _quotesWindows = 
     new SynchronizedDictionary&amp;lt;Security, QuotesWindow&amp;gt;();

private readonly SynchronizedDictionary&amp;lt;MarketDepth, QuotesWindow&amp;gt; _changedDepths = 
     new SynchronizedDictionary&amp;lt;MarketDepth, QuotesWindow&amp;gt;();&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt; &lt;br /&gt;&lt;br /&gt;Просто я думал логика должна была быть примерно такая - достаточно держать лишь один словарь - _quotesWindows и при получении обновленного MarketDepth - найти соответствующий ему элемент в _quotesWindows и обновить _quotesWindows.Value. Разве не так?&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Или другими словами можно было бы исключить&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;
private readonly SynchronizedDictionary&amp;lt;Security, QuotesWindow&amp;gt; _quotesWindows = new SynchronizedDictionary&amp;lt;Security, QuotesWindow&amp;gt;(); &lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt; &lt;br /&gt;&lt;br /&gt;т.к. между экземпляром инструмента (Security) и экземпляром стакана (MarketDepth) существует однозначная связь, а security - экземпляр Security определяется, как из экземпляра стакана depth (MarketDepth), так и экз-ра котировок стакана, привязанного к окну  QuotesWindow (ObservableCollection&amp;lt;Quote&amp;gt;)&lt;br /&gt;&lt;br /&gt;Но, в наст. реализации, _quotesWindows - это экземпляр окна котировок, содержащее коллекцию котировок, не содержащие внутри себя идентификацию инструмента (стакана) или стакана (инструмента) этих котировок:&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;

public partial class QuotesWindow
{
    public QuotesWindow()
    {
        Quotes = new ObservableCollection&amp;lt;Quote&amp;gt;();
	InitializeComponent();
     }

     public ObservableCollection&amp;lt;Quote&amp;gt; Quotes { get; private set; }
}  
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href='http://i.imgur.com/ZF7sw.jpg' class='lightview' data-lightview-options="skin: 'mac'" data-lightview-group='mixed'&gt;&lt;img src="http://i.imgur.com/ZF7sw.jpg" style='max-width: 600px;' alt="QuotesWindow.xaml" title="QuotesWindow.xaml" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Зато для этого есть словари, из которых по экземпляру инструментов (Security) или стаканов (MarketDepth) можно извлечь экземпляр коллекции котировок - QuotesWindow, т.е. ObservableCollection&amp;lt;Quote&amp;gt;&lt;br /&gt;&lt;br /&gt;Насколько я понимаю, есть другие необходимости&lt;br /&gt;&lt;ul&gt;&lt;li&gt;обычно для одного и того же инструмента (в терминалах и программах S#) можно открывать несколько окон одного и того же стакана, для каждого со своим клоном-копией (данных) стакана.&lt;br /&gt;&lt;br /&gt;В общем, неочевидно, что нужны твкие усложнения, при том, что теряется гибкость и структурность + см. следующее соображение&lt;br /&gt;&lt;br /&gt;&lt;li&gt;В рассматриваемом приложении, данные инструментов копируются-дублируются во много окон &lt;br /&gt;- SecuritiesWindows, котировки-стакана (каждого инструмента) QuotesWindow и др. (MyTradesWindows, OrdersWindow, PositionsWindows и др.) . показываются в разных окнах с копиями данных, некоторые из которых задублированные копии одних и тех же сущностей (например - инструмент) &lt;br /&gt;Поэтому делать из экземпляров объектов инструмента синглтоны - неоправданно усложнять, при этом теряя в гибкости &lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;FlashPlayer &lt;a href="https://stocksharp.ru/posts/m/23289/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;
private readonly SynchronizedDictionary&amp;lt;Security, QuotesWindow&amp;gt; _quotesWindows = 
     new SynchronizedDictionary&amp;lt;Security, QuotesWindow&amp;gt;();

private readonly SynchronizedDictionary&amp;lt;MarketDepth, QuotesWindow&amp;gt; _changedDepths = 
     new SynchronizedDictionary&amp;lt;MarketDepth, QuotesWindow&amp;gt;();&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt; &lt;br /&gt;&lt;br /&gt;Далее происходит подписка на обновление стаканов trader.MarketDepthsChanged += TraderOnMarketDepthsChanged, и вот совсем мне непонятно, что делается в TraderOnMarketDepthsChanged: &lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;strong&gt;Код&lt;/strong&gt;&lt;div class="innercode"&gt;&lt;pre class="brush:csharp"&gt;

private void TraderOnMarketDepthsChanged(IEnumerable&amp;lt;MarketDepth&amp;gt; depths)
{
    foreach (var depth in depths)
    {
        var wnd = _quotesWindows.TryGetValue(depth.Security);

        if (wnd != null)
              _changedDepths[depth] = wnd;
     }
}
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Что тут происходит, как я понимаю: рассматриваем каждый обновившийся стакан и ищем соответствующее ему окно стакана в _quotesWindows: &lt;br /&gt;var wnd = _quotesWindows.TryGetValue(depth.Security);&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Насколько я понимаю, котировки дублируются в 2х словарях и при их обновлении их надо скопировать (синхронизировать) из одного в другой &lt;br /&gt;&lt;br /&gt;&lt;div class="quote"&gt;&lt;span class="quotetitle"&gt;FlashPlayer &lt;a href="https://stocksharp.ru/posts/m/23289/" class="quote_nav"&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="innerquote"&gt;Далее что происходит в этой строчке: _changedDepths[depth] = wnd; ? Откуда мы знаем, что в словаре _changedDepths есть элемент с ключом depth? &lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Ну, так они для того и называются синхронизированными&lt;br /&gt;&lt;br /&gt;Их вначале инициализируют &amp;quot;одинаково&amp;quot; (т.е. синхронизованно) по (структурам данных)  выбранным инструментов (каждой из которых соответствует стакан, вернее структура данных стакана), обновления котрых нас интересуют, а потом их танцуют&lt;br /&gt;&lt;br /&gt;Детали можно посмотреть с помощью ReSharper</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
  <entry>
    <id>https://stocksharp.ru/posts/m/23289/</id>
    <title type="text">Подскажите пожалуйста - как работает GuiDispatcher.AddPeriodicalAction? Судя из названия метода - де...</title>
    <published>2013-01-10T18:04:14Z</published>
    <updated>2013-01-10T18:04:14Z</updated>
    <author>
      <name>FlashPlayer</name>
      <uri>https://stocksharp.ru/users/16669/</uri>
      <email>info@stocksharp.ru</email>
    </author>
    <content type="html">Подскажите пожалуйста - как работает GuiDispatcher.AddPeriodicalAction? Судя из названия метода - действие вызывается периодически - но с какой частотой. Пример использования встречается в SampleGui, где с помощью этого метода обновляется информация в открытых стаканах. Логика там, как я понимаю, следующая - ведется два синхронизированных словаря ключ-значение: один - инструмент/окно стакана, другой - рыночный стакан/окно стакана. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;		private readonly SynchronizedDictionary&amp;lt;Security, QuotesWindow&amp;gt; _quotesWindows = new SynchronizedDictionary&amp;lt;Security, QuotesWindow&amp;gt;();&lt;br /&gt;                private readonly SynchronizedDictionary&amp;lt;MarketDepth, QuotesWindow&amp;gt; _changedDepths = new SynchronizedDictionary&amp;lt;MarketDepth, QuotesWindow&amp;gt;(); &lt;br /&gt;&lt;br /&gt;Далее происходит подписка на обновление стаканов trader.MarketDepthsChanged += TraderOnMarketDepthsChanged, и вот совсем мне непонятно, что делается в TraderOnMarketDepthsChanged: &lt;br /&gt;&lt;br /&gt;                private void TraderOnMarketDepthsChanged(IEnumerable&amp;lt;MarketDepth&amp;gt; depths)&lt;br /&gt;		{&lt;br /&gt;			foreach (var depth in depths)&lt;br /&gt;			{&lt;br /&gt;				var wnd = _quotesWindows.TryGetValue(depth.Security);&lt;br /&gt;&lt;br /&gt;				if (wnd != null)&lt;br /&gt;					_changedDepths[depth] = wnd;&lt;br /&gt;			}&lt;br /&gt;		}&lt;br /&gt;&lt;br /&gt;Что тут происходит, как я понимаю: рассматриваем каждый обновившийся стакан и ищем соответствующее ему окно стакана в _quotesWindows: &lt;br /&gt;                               var wnd = _quotesWindows.TryGetValue(depth.Security);&lt;br /&gt;&lt;br /&gt;Далее что происходит в этой строчке: _changedDepths[depth] = wnd; ? Откуда мы знаем, что в словаре _changedDepths есть элемент с ключом depth? И зачем на каждом обновлении стакана depth мы переприсваиваем значение wnd в словаре? Ну и самый главные вопрос - как потом в wnd появляются новые котировки с обновленного depth? Как работает .AddPeriodicalAction?&lt;br /&gt;&lt;br /&gt;Просто я думал логика должна была быть примерно такая - достаточно держать лишь один словарь - _quotesWindows и при получении обновленного MarketDepth - найти соответствующий ему элемент в _quotesWindows и обновить _quotesWindows.Value. Разве не так?&lt;br /&gt;&lt;br /&gt;Я еще только начинаю разбираться в программировании такого уровня, так что сильно не бейте и спасибо за помощь.&lt;br /&gt;</content>
    <rights type="html">Copyright @ StockSharp Platform LLC 2010 - 2025</rights>
  </entry>
</feed>