There are two things in your code:
1. You received a quote from one stream (AKA producer - market data feed).
2. You send the quote to another stream (consumer AKA StrategyAssembler).
At this point, there is competition in the quote, in other words, the producer stream and each consumer stream (i.e. each instance of the strategy) can change the quote you just provided. In order for you to resolve the conflict, you must do one of three things:
- Synchronize between all threads with access to quote.
OR - Make the quote unchanged (and make sure the manufacturer does not replace it).
OR - Give each buyer a copy of the quote.
In your case, I suggest you use the third option, because locking is more expensive than copying a quote (I hope your quotes are not very large) ... option two is also good, but your strategy should not change the quote.
By providing each consumer with a copy of the quote that you provide so that they do not share any data, so no other thread will change the quote and you will resolve the conflict. If your strategies do not create any other flows, then you are done.
In general, you should avoid blocking, and you should try to minimize data sharing, but if you are HAVE TO exchanging data between threads, you should do it right:
For your strategies to synchronize correctly, they must synchronize the same QuoteLocker object , i.e. QuoteLocker should be visible for each thread. Even if you do it right and you synchronize your strategies (block QuoteLocker ), you may also not have threads ... you will use the overhead of context switching + locking, and your strategies will be executed sequentially for the same quote.
Update for comments: If you leave the code as is (which means that you provided a copy of the quote for each thread), then I do not understand why your other strategies will not receive this quote until the first strategy is completed ... yours the first strategy will most likely begin to work while threads are being created for other strategies. The thing is that your strategies run in a separate thread to avoid this problem ... you start a new thread so that your other strategies do not expect from each other.
This part of the code is likely to be completed before all your threads start working ...
foreach (StrategyAssembler assembler in StrategyAssembleList.GetStrategies()) { BackgroundWorker thread = strategyThreadPool.GetFreeThread(); if (thread != null) { thread.DoWork += new DoWorkEventHandler(assembler.NewIncomingQuote); Quote copy = CopyTheQuote(quote);
Is your market feed a changing actual quote when creating threads? Market feeds usually provide snapshots, so if something doesn’t change your quote while creating the threads, then the design above should be great. If there is a problem with the design, then I can give you the manufacturer and several consumer designs based on the blocking queue, which is also very effective ( you can check this discussion for an idea of how this works , and I can tell you how to change it for your specific example).