В вашем коде происходят две вещи:
1. Вы получили цитату из одной ветки (производитель АКА, рыночный фид данных).
2. Вы отправляете цитату в другую ветку (потребитель AKA StrategyAssembler).
На данный момент существует утверждение о кавычке, другими словами, поток производителя и каждый потребительский поток (т. Е. Каждый экземпляр стратегии) может изменить цитату, которую вы только что предоставили. Для того, чтобы вы удалили утверждение, вы должны сделать одну из трех вещей:
- Синхронизация между всеми потоками с доступом к цитате.
ИЛИ
- Сделайте цитату неизменной (и убедитесь, что производитель не заменит ее).
ИЛИ
- Дайте каждому потребителю копию цитаты.
В вашем случае я бы посоветовал вам воспользоваться третьим вариантом, потому что блокировка обходится дороже, чем копирование цитаты (надеюсь, ваши цитаты не очень большие) ... второй вариант тоже хорош, но ваша стратегия не должна изменять цитату .
Предоставляя каждому потребителю копию предложения, вы гарантируете, что он не передает никакие данные, поэтому никакой другой поток не изменит предложение, и вы устраните конфликт. Если ваши стратегии не создают никаких других потоков, то вы закончили.
Как правило, вам следует избегать блокировок и стараться свести к минимуму обмен данными, но если вы ДОЛЖНЫ * обмениваться данными между потоками, вам следует сделать это правильно:
Для правильной синхронизации ваших стратегий они должны синхронизироваться на одном и том же объекте QuoteLocker
, т. Е. QuoteLocker
должны быть видны каждому потоку. Даже если вы делаете это правильно и вы синхронизируете свои стратегии (блокируете на QuoteLocker
), то у вас также могут не быть потоков ... вы будете выполнять накладные расходы на переключение контекста + блокировку, и ваши стратегии будут выполняться последовательно для та же цитата.
Обновление по комментариям:
Если вы оставите код как есть (имеется в виду, что вы предоставляете копию цитаты для каждого потока), то я не понимаю, почему ваши другие стратегии не получат цитату, пока не завершится первая стратегия ... ваша первая стратегия будет наиболее скорее всего, начнут работать, пока создаются потоки для других стратегий. Весь смысл в том, чтобы ваши стратегии выполнялись в отдельном потоке, чтобы избежать именно этой проблемы ... вы запускаете новый поток, чтобы другие ваши стратегии не дожидались завершения друг друга.
Эта часть кода, скорее всего, завершится даже до того, как все ваши потоки начнут работать ...
foreach (StrategyAssembler assembler in StrategyAssembleList.GetStrategies())
{
BackgroundWorker thread = strategyThreadPool.GetFreeThread();
if (thread != null)
{
thread.DoWork += new DoWorkEventHandler(assembler.NewIncomingQuote);
Quote copy = CopyTheQuote(quote);// make an exact copy of the quote
thread.RunWorkerAsync(copy);
}
}
Изменяет ли ваш рыночный фид фактическую котировку при создании тем? Рыночные каналы обычно предоставляют моментальные снимки, поэтому, если что-то не меняет вашу цитату, пока вы создаете темы, то приведенный выше дизайн должен быть просто в порядке. Если есть проблема с дизайном, то я могу дать вам дизайн для нескольких производителей и потребителей, основанный на очереди блокировки, которая также очень эффективна (, вы можете проверить это обсуждение для идеи о том, как это работает и я могу рассказать вам, как изменить его для вашего конкретного примера).