2005-10-21

threadvar for dotnet

I needed a global variable, of sorts. NActiveRecord, the ORM (object-relational mapping) library I’m creating, needs to be able to perform multiple database operations in a single transaction. This means I must either obtain a transaction handle and pass it around like a toke to every class and object that needs it—muddying layers and APIs and increasing fragility—or the classes need to be able to share a transaction handle behind the scenes, out of view of business logic.

However, ASP.NET is a multi-threaded environment and all manor of grief awaits the unwary—usually just after deployment to production—if proper respect is not paid to concurrency issues. What I needed was what Delphi calls a threadvar—a per-thread global variable.

I was midway through implementing a property that would store the current transaction handle in a static dictionary, indexed by the current thread’s ID—with a lock protecting it from being accessed simultaneously by multiple threads—when a slip of the fingers caused Visual Studio’s IntelliSense to pop up ThreadStaticAttribute. What’s this?

Online help tells me “A static field marked with ThreadStaticAttribute is not shared between threads. Each executing thread has a separate instance of the field, and independently sets and gets values for that field. If the field is accessed on a different thread, it will contain a different value.”

My implementation was reduced to:

[ThreadStatic]
protected static FbTransaction trans;

Nice.