Welcome to WindowsClient.net | Sign in | Join

Zuker On Foundations

The realm of .NET (WPF, WCF and all around)

Threading Thoughts

Multi-threading is an important concept, we can all agree to that.

We could find ourselves using threads even if we're not in an environment which is multi-threaded by nature. (services and such)

But how do we write atomic code? (Thread-Safe)
Well, there isn't a simple answer to that, obviously.

The key thing is: Be aware of any instance used concurrently.

You can read the following post:
Implementing The Singleton Pattern in C#
It describes various ways to implement the singleton pattern specifically, but you can take a lot from it to other scenarios as well.

Plus, there's the MSDN article:
Managed Threading Best Practices

Some key points I pulled out myself:

Singleton Pattern -

  • Use Lazy initialization / Double-check lock mechanism (consider defining the field as volatile)

If you do use the double-check, you can apply what is described at the bottom.

Instance in concurrent environment -

  • Use Interlocked where possible to ensure thread-safety with performance optimization
  • Perform Locks & Monitoring on reference-type objects (not value-types, not types and such)

Use of Interlocked -

Statement
lock(lockObject)
{
    myField++;
}

Change to
System.Threading.Interlocked.Increment(myField);

Statement
if (x == null)
{
    lock (lockObject)
    {
        if (x == null)
        {
            x = y;
        }
    }
}

Change to:
System.Threading.Interlocked.CompareExchange(ref x, y, null);

A quick example for implementing locking with a handle object using Interlocked:
public class SyncUsingSyncHandle
{
   private object synchHandle;
   private object GetSynchHandle()
   {
      System.Threading.
Interlocked.CompareExchange(ref synchHandle,
                  new object(), null);
 
      return synchHandle;
   }
 
  
private void DoSomethingSynchronized()
   {
      lock (GetSynchHandle())
      {
         //perform logic
      }
   }
}
 

Note: You can simply perform lazy instantiation with the handle and lock its instance, but this way you're using Interlocked and its optimizations.

Writing atomic code is certainly a crucial concept when working in concurrent environments, we should "Think Runtime".

Posted: Jun 12 2008, 11:29 AM by zuker | with no comments
Filed under:

Comments

No Comments

Leave a Comment

(required) 

(required) 

(optional)

(required) 

Page view counter