Threadstatic V.S. Threadlocal<T>: Is Generic Better Than Attribute

ThreadStatic v.s. ThreadLocalT: is generic better than attribute?

Something the blog post noted in the comments doesn't make explicit, but I find to be very important, is that [ThreadStatic] doesn't automatically initialize things for every thread. For example, say you have this:

[ThreadStatic]
private static int Foo = 42;

The first thread that uses this will see Foo initialized to 42. But subsequent threads will not. The initializer works for the first thread only. So you end up having to write code to check if it's initialized.

ThreadLocal<T> solves that problem by letting you supply an initialization function (as Reed's blog shows) that's run before the first time the item is accessed.

In my opinion, there is no advantage to using [ThreadStatic] instead of ThreadLocal<T>.

CallContext.LogicalGetData() vs ThreadLocal/ThreadStatic

Yes, the logical call context will work as an async-local.

AsyncLocal<T> uses the logical call context on the full .NET framework - it just has a nicer API and will work with the upcoming .NET Core platform while the logical call context will not.

Remember to only store immutable data, as I describe on my blog.

Also, there is a definite performance impact with async-local values. It would almost definitely be more performant to pass the parameter explicitly, perhaps as part of your own RequestContext type. ASP.NET vCore is moving away from HttpContext.Current; it still has the concept of HttpContext, but it doesn't act as an async local anymore - it's passed explicitly.

Does C# have a ThreadLocal analog (for data members) to the ThreadStatic attribute?

Enter .NET 4.0!

If you're stuck in 3.5 (or earlier), there are some functions you should look at, like AllocateDataSlot which should do what you want.

Why use data slot over ThreadLocal?

As I said in comments, ThreadLocal<T> is implemented using the Thread Local Dataslots API. You can confirm that by looking at the ThreadLocal source code. Unless you have some compelling reason to work at the Windows API level, you're better off using ThreadLocal<T>.

One very good reason to choose ThreadLocal<T> is that it makes sure that the value is initialized for every thread. ThreadStatic does not do that, and your interface to thread local data slots API would have to code specially for it, too. See https://stackoverflow.com/a/18337158/56778 for a bit more info.

Use ThreadLocal<T> with lazy initialization. You'll save yourself a lot of pain.

ThreadLocal and generics

From a type perspective, what you're trying to do at the moment really doesn't make sense.

You have a static property Instance but its type its completely ambiguous because it's impossible to resolve the meaning of 'T. In order to do this you need to propagate the type annotation up to the containing type, e.g.:

type LeftoverPool<'T> private () =
static let instance = new ThreadLocal<'T[]>(fun () -> Array.zeroCreate<'T> (Vector<'T>.Count))
static member Instance = instance.Value


Related Topics



Leave a reply



Submit