5

What is the difference between this ThreadName and LocalName in the code below? Are they both ThreadLocal?

// Thread-Local variable that yields a name for a thread
ThreadLocal<string> ThreadName = new ThreadLocal<string>(() =>
{
    return "Thread" + Thread.CurrentThread.ManagedThreadId;
});

// Action that prints out ThreadName for the current thread
Action action = () =>
{
    // If ThreadName.IsValueCreated is true, it means that we are not the 
    // first action to run on this thread. 
    bool repeat = ThreadName.IsValueCreated;
    String LocalName = "Thread" + Thread.CurrentThread.ManagedThreadId;
    System.Diagnostics.Debug.WriteLine("ThreadName = {0} {1} {2}", ThreadName.Value, repeat ? "(repeat)" : "", LocalName);
};

// Launch eight of them.  On 4 cores or less, you should see some repeat ThreadNames
Parallel.Invoke(action, action, action, action, action, action, action, action);

// Dispose when you are done
ThreadName.Dispose();
Helic
  • 907
  • 1
  • 10
  • 25
  • Have you read the documentation for `ThreadLocal`? – Jon Skeet Aug 22 '14 at 10:27
  • `string LocalName` is very ThreadLocal. As long as it's not closed-over by a lambda. – H H Aug 22 '14 at 10:36
  • 1
    @JonSkeet yes, that is why I came with this question. the example is modified from the sample code from http://msdn.microsoft.com/en-us/library/dd642243%28v=vs.110%29.aspx – Helic Aug 22 '14 at 10:37
  • 2
    @JonSkeet - did you? The MSDN page I found only has _"Provides thread-local storage of data."_ (and member specs and an example). – H H Aug 22 '14 at 10:37
  • @Helic - but I don't get the comparison with a local var. It is functionally closer to `static`. – H H Aug 22 '14 at 10:41
  • Thread.CurrentThread Gets the currently running thread... as Henk implies... ThreadLocal is evaluated lazily so beware. Investigate Thread.GetData and Thread.SetData... This may interest you http://theburningmonk.com/2010/10/threadstatic-vs-threadlocal/ – Paul Zahra Aug 22 '14 at 10:42
  • See the answers to related question http://stackoverflow.com/questions/2202735/what-are-the-advantages-of-instance-level-thread-local-storage – bug-a-lot Aug 22 '14 at 10:52
  • 1
    @HenkHolterman: Ick, that's really not very good. Still, the question would be better having stated that: "I've tried reading the documentation (here) and I don't understand X"... – Jon Skeet Aug 22 '14 at 11:01

2 Answers2

3

LocalName is not thread-local. It is scoped to the execution of the surrounding lambda. You will get a fresh value each time the lambda runs (and concurrent runs are independent). With a ThreadLocal you get a fresh value per thread. Repeatedly invoking ThreadName.Value will only give you one value if it happens to be on the same thread.

In this example both are equivalent because Thread.ManagedThreadId is also thread-local. Try Guid.NewGuid().

usr
  • 168,620
  • 35
  • 240
  • 369
  • The values are equal but they're not equivalent. ThreadName is reused by thread pool in Parallel.Invoke. – norekhov Aug 22 '14 at 11:52
  • @norekhov Not sure what you're saying. Here, `ThreadName` always hands out the same value that `LocalName` also has. – usr Aug 22 '14 at 11:56
2

There is a thread pool. So if a thread is resused for a second action you will get "repeat". LocalName is a local variable.

norekhov
  • 3,915
  • 25
  • 45