views:

89

answers:

3

I'm writing a class library that will offer some asynchronous processing, and want to try and avoid running into threading issues later on down the line. So I'm after any suggestions people can make to avoid running into issues later on, and instead start with a good design.

Some of the situations that I can see that might cause problems, and am not neccessairly sure the best way to resolve:

1) I have a class that takes an IEnumerable and uses a ToList to construct an IList. The T's are a class declared as public within my assembly. Upon starting an async process this IList is used to create a new collection, however at this point the calling assembly may be modifying the original T's used to generate my new internal collection.

2) I have a Boolean property that I'm expecting the user to use in a polling loop. I'm fairly sure that this won't be a problem with me setting the property in my assembly?

3) I regularly used an internal collection that needs to be used on two seperate threads. I'm currently planning to use a synchronized collection and clone it whenever I need a copy... although I'm hoping this won't be too slow.

4) Throughout my async method I'm wanting to fire events whenever the progress or status changes. Do I need to be aware of anything when firing events from processing threads? Again with some of these I need to pass a variable which will be taken as a clone of something used internally within the processing threads to try and avoid any issues with the user changing it.

Thanks in advance for any assistance!

Ian

+2  A: 

1) Try to make your types immutable if possible. If that's not possible, you need to work on appropriate locking.

2) Make the underlying variable volatile so that updates get seen in all threads

3) We'd need more information to be able to sensibly comment.

4) The event handlers would need to be aware that they could be called on multiple threads. You should also look at a fully thread-safe event pattern if you need to be able to subscribe to and unsubscribe from events from various threads.

Jon Skeet
+1  A: 

2: watch out for volatile (see here for example why); and don't do a "tight" loop. Signals (such as a Monitor.Pulse, or a ManualResetEvent, etc) are often preferred

4: if this is for display purposes, you'll need to marshal these back to the UI thread

Marc Gravell
A: 

Thanks guys,

1) Unfortunately I don't think making my types immutable would work, so I might have to lock them. Fortunately it is only during the initial set up of the async method as I create simplified internal copies of most class instances for various reasons, at which point I don't care what the user does with the originals.

2) The volatile keyword looks like something I definitely need, so will be putting that in.

3) I'm going to have two threads running that both need to access an Collection< U>. Once they've got this collection, they'll use it extensively, and also modify various properties for each U instance. Once they've finished they'll save a few simple properties (e.g. Guid), throw the collection away and need to start again. Therefore I'm thinking that a ReadOnlyCollection< U> should be created initially, then for each of these threads when the processing starts, they'll run some form of a Clone method, and churn the output into a new IList< U> for example which they'll do they're proessing on.

4) That's useful Jon, the event handling can be called from multiple threads so I'll certainly use something along those lines.

Ian