views:

55

answers:

3

I have a static class that holds a dictionary of objects. I have multiple threads that access this dictionary and create objects on it that are specific to that thread. How and when can I remove entries from the dictionary when a thread is "done"?

Basically this is a static class for an ASP.NET application that all requests can have "isolated objects" (that are related to the current thread) created in the dictionary. But, I don't really want to be tied to ASP.NET.

Does this make sense?

+4  A: 

You can decorate a static field with a [ThreadStatic] attribute and each thread will see its own value. If you are using .NET 4.0, you can use ThreadLocal<T> to do that too. Basically, you'd have a separate dictionary for each thread holding its own objects rather than saving all objects in a single dictionary.

Mehrdad Afshari
Ok that's cool to know. Only *one* more condition. This dictionary *might* hold objects that can be available to *all* threads. The key is of type `Type` (I'm creating a simple IoC container), and don't really want to test two dictionaries... any other ideas (though I really like `ThreadStatic/ThreadLocal<T>` so I'll check them out). Also, would there be a way to know when it's disposed so I can dispose of each item properly?
TheCloudlessSky
@TheCloudlessSky: If you want to share stuff between threads, ThreadStatic is not an option. However, you can hold references to the same objects in two thread local dictionaries. If you need to share the dictionary itself, ThreadStatic is not an option. You'll have to make sure to lock the dictionary appropriately as you are making changes across threads. Regarding the disposal of objects: a dictionary is a managed resource. By losing references to it, it'll eventually get garbage collected. It doesn't get "disposed" automatically. You can manually `Dispose` the contents as the thread ends.
Mehrdad Afshari
@Mehrdad - How do I know when the current thread ends? I have no control over the threads (ASP.NET).
TheCloudlessSky
@TheCloudlessSky: In case of ASP.NET, I think `EndRequest` event is a good approximation.
Mehrdad Afshari
A: 

Assuming that you store the id of the thread (or some other unique identifier) with the objects you could fire an event from the thread closing code - with this unique id - to let the dictionary know that the thread has finished with it's objects.

Your static class could subscribe to this event and then loop through the dictionary removing all objects that have this id.

I think.

ChrisF
Yes, but *which* event ;)
TheCloudlessSky
@TheCloudlessSky - Create your own event.
ChrisF
Ok, but I'm not controlling the creation/deletion of the threads (ASP.NET is). I have no control of the "current thread".
TheCloudlessSky
@TheCloudlessSky - You must have control over the threads themselves. Are they `BackgroundWorker` threads, or just threads created via `new Thread()`?
ChrisF
@TheCloudlessSky - If it's the former you fire the event in the `Worker_RunWorkerCompleted` method. If it's the latter you can just fire the event at the end of the method you pass to `ThreadStart`
ChrisF
@ChrisF - as stated in the original question, they're threads from an ASP.NET application. Each request spawns a new thread that I don't have control over.
TheCloudlessSky
A: 

It sounds like your dictionary is being used as a cache.

Have you considered using an existing caching solution instead of rolling your own? The Enterprise Library has a nice caching block that allows you an enormous amount of flexibility in how you manage the lifecycle of the objects you cache, including timing them out after a period of inactivity. (i.e. thread has disappeared)

Andrew Anderson
It's not for a cache, I'm creating a simple IoC container for my own learning.
TheCloudlessSky
Ah, cool - in that case please disregard this entirely; the application wasn't immediately clear from your initial description. Happy learning! =)
Andrew Anderson
Sorry for the bad description.. :)
TheCloudlessSky