Как реализовать синхронизацию потоков, работающих с общими данными?

Пишу вопрос на данном сайте первый раз, поэтому могу немного некорректно выразить мысль. Пишу программу для торговли на бирже. Есть класс, в котором 3 события и список объектов List<Robot> Robots

private void ChangeInsPrice(object sender, EventArgs e)
{
  lock(object)
  {
     foreach(Robot rb in Robots)
     {
     }
  }
}

private void AddOrder(object sender, EventArgs e)
{
    lock(object)
    {
       foreach(Robot rb in Robots)
       {
       }
    }
}

private void AddData(object sender, EventArgs e)
{
   lock(object)
   {
     foreach(Robot rb in Robots)
     {
     }
   }
}

В событии AddData с сервера приходят данные каждую минуту. Мы проверяем некоторые условия и если что, указываем роботу войти в позицию, купить акцию. Далее при изменении цены, вызывается событие ChangeInsPrice и, при некоторых условиях, мы указываем роботу выйти из позиции, продать акцию. После каждой покупки\продажи вызывается событие AddOrder. Я всё реализовал через lock, но понимаю, что после первого и третьего события, всем потокам необходимо ожидать того, чтобы вызвалось событие AddOrder и после этого уже продолжать свою работу.

А то проблема в том, что после выхода из позиции робота, я не успеваю получить сообщения с сервера в событии AddOrder, а вызывается другое уже событие. Получается, нужно не Lock, а что-то другое, которое скажет, что мы ожидаем, пока вызовется событие AddOrder и когда оно пройдет, мы продолжим работу.

P.s. Примерная блок схема на решение

  1. Заходим в AddData
  2. Остальные потоки ожидают если вызвалось событие ChangeInsPrice
  3. Если мы покупаем\продаем, то встаем в ожидание вызова и обработки события AddOrder.
  4. Продолжаем выполнение AddData.
  5. После выполнение AddData, остальные потоки могут заходить в событие ChangeInsPrice.

Аналогично и с ChangeInsPrice.

Я так понимаю, что идеально для моего варианта подойдет AutoResetEvent где в событиях ChangeInsPrice и AddData после покупки я прописываю WaitOne(), и после в AddOrder я прописываю Set()


Ответы (0 шт):