Connecting Tech Pros Worldwide Help | Site Map

Class Library with Thread Safety

Expert
 
Join Date: Jan 2008
Location: York
Posts: 179
#1: Aug 12 '09
Right, here goes. I'm designing a class library that runs a heuristic on several threads and therefore has to be thread safe. I'm going to outline the current design in a second, but I'm not sure that it's quite right, so I'd like some suggestions.

How it currently works:

1) A collection of a custom class, A are defined by the developer using the class library.
2) To ensure that the A's aren't modified during execution (this could be very bad) they aren't directly used. Instead prior to execution they are convert to 'InternalA' instances. These are very similar, but mean they are safer and allow a single A instance to be represented by several InternalA instances.

This leads to something like the following:

Expand|Select|Wrap|Line Numbers
  1. public class A
  2. {
  3.    public double Stock { get; set;}
  4.    internal IEnumerable<InternalA> MakeInternalAs() {}
  5. }
  6.  
  7. internal class InternalA : ICloneable
  8. {
  9.    public double Stock { get; set;}
  10. }
  11.  
You'll notice that InternalA is also cloneable. This is important because I don't want the threads interferring with each other. So instead all the values required are cloned and these copies used, preserving the originals.

Expand|Select|Wrap|Line Numbers
  1. internal void Run()
  2. {
  3.    List<A> As = CloneInternalACollection();
  4. }
  5.  
Firstly I'm not sure that I really like the whole A, InternalA thing, but I need it to be threadsafe, and I need it to be fast. Things are going to get read and modified a lot during this heuristic and I don't want to slow it down too much with overkill on lock() etc.

Secondly, my InternalA class has a check in it.

Expand|Select|Wrap|Line Numbers
  1. InternalA
  2. {
  3.    public Boolean HasValidStock(double demand) {}
  4. }
  5.  
This means that all my logic is quite tightly coupled with my internal classes. It means that I can't now go ahead and let developers extend my decision logic, because the A instance is never used outside the conversion process.

One way would be to use delegates, but then they'd probably be static and be something more like the following which I don't like

Expand|Select|Wrap|Line Numbers
  1. public static Boolean HasValidStock(double myStock, double demand)
  2.  
So I suppose I'm after suggestions on a better design, or maybe if people thing the static overrides make sense, considering the people on these forums are similar to the intended audience. What are your thoughts?

Thanks
Reply