Take the 2-minute tour ×

I'm working on an application that process pipelines in separate threads. During my tests I have seen that if a process is "lightweight" or the CLR determines that this is going to end quickly CLR recycle this thread rapidly and various units of work can share at the same time the same thread.

On the contrary if a process take's some time or has more load CLR open different threads.

To me all that difficult TLS Thread local storage programming.

In fact my application pipelines take some time to process and it seems that CLR is always assigning one managed thread for each other. BTW if in some case two pipelines share one managed thread they will collide because they use TLS variables.

After all that here comes the real question... Can I do the assumption that If a process takes some time/load it will always use it's own thread, or am I crazy doing that?

For what I have been reading managed threads in .net 3.5 is like acting with a kind of black box. So perhaps this question can never really be responded.


With process I am refereing to the dictionary definition A series of actions, changes, or functions bringing about a result an not the computer process you identify in task manager.

share|improve this question
Define 'process'. Your use of process seems to differ somewhat from the standard definition. –  Kendall Frey Mar 21 '12 at 22:16
Do not use thread local storage if the variables are not actually meant to be per thread. If you need per activity, then associate the variables with a given activity. –  dlev Mar 21 '12 at 22:19
Hard to decipher this question. I assume you are just seeing the threadpool manager starting additional threads when the running ones don't complete in a timely way. –  Hans Passant Mar 21 '12 at 23:58
@Hans Passant yes I guess I'm seeing CLR thread manager starting new threads when a running one don't complete in a timely way, good description. That should be a good characteristic of thread pool but difficult TLS programming. –  guillem Mar 22 '12 at 7:22
What @dlev says is true but I have learn it the hard. And now It's more difficult to me to redo everything to work this way. –  guillem Mar 22 '12 at 7:22
add comment

2 Answers


Process always uses its own threads. It's not possible access other process's thread, not that I'm aware of.

share|improve this answer
I'm aware of that the question is that if two CLR processes/actions can share the same managed thread. –  guillem Mar 22 '12 at 6:47
@guillem: infact I respond that it's not possible, as much as I'm aware of. –  Tigran Mar 22 '12 at 7:58
well actually what I have seen is that if an action doesn't take long can share same managedThreadId with others so they share same thread, although is CLR who decide that. –  guillem Mar 22 '12 at 8:37
@guillem: the thread is in the scope of the single process. I'm not really sure what you mean exactly saying "share" ID. –  Tigran Mar 22 '12 at 8:41
@guillem: agree. It's hardly possible immagine some runtime mechanism that validates threads against the assigned task load and so make the thread behave differently. Their management is common for all threads heavy or not. –  Tigran Mar 22 '12 at 22:47
show 2 more comments

Code run from a threadpool thread should not place anything in thread-local storage which it is not going to remove via finally block. If you need to ensure that any thread-local storage used by a piece of code will die after that code finishes executing, you need to explicitly either clean up the storage or run that code in its own thread.

share|improve this answer
I wasn't aware of that... Isn't that a job for the garbage collector? Can I see this with the debugger? What if I use [ThreadStatic] decorator? –  guillem Mar 22 '12 at 7:27
@guillem: The garbage collector's job is to allow the reuse of memory which is otherwise inaccessible. If a routine called by the threadpool sets a [ThreadStatic] field and exits while it is still set, that field will be accessible to any routine which is run by the threadpool and happens to be given the same thread. Because there exists a sequence of events by which the field could be accessed, the garbage collector has to preserve it. One underappreciated characteristic of the garbage collector is that it has minimal concept of whether something is or will ever be "useful". –  supercat Mar 22 '12 at 14:43
@guillem: Items held in a WeakReference and items which override Object.Finalize are special cases, since the garbage collector can invalidate a WeakReference when no strong reference exists to its target, and can queue objects for finalization when a reference exists in the finalization queue but nowhere else. Outside those cases, though, the fact that a means exists by which an object could be referenced will be sufficient to prevent the garbage collector from collecting it, even if the object could disappear without anyone missing it. –  supercat Mar 22 '12 at 14:55
@supercatthat I'm running a small project with a [Threadstatic] static boolean and although threads are recycled this boolean is always reset to false –  guillem Mar 22 '12 at 16:41
@guillem: Via what means are you determining that the threads (and not just their ids) are being recycled? –  supercat Mar 22 '12 at 17:01
show 3 more comments

Your Answer


