This is a mirror of official site: http://jasper-net.blogspot.com/

Wrapping a not thread safe object

| Tuesday, March 22, 2011
Introduction

    A colleague came to me with a question the answer for seemed very straight forward, yet an implementation took us more than a few minutes. The question was: I have a legacy object which is not thread safe, and all its methods, by its nature, synchronous. It was originally written to run on GUI thread in client application. Later on, this object had to be moved to server where it has to face new challenges. Now the requests to use this method come from the network, means, we face thread safety problem, we have to make sure only one method runs simultaneously on this object. On the other hand methods are synchronous and it would be a bad practice to keep our network "waiting". This article shows how to create a simple wrapper around the object which will synchronize the calls to original object and expose standard async methods.

An unsafe object to wrap

    First lets create an unsafe class we will later on wrap, this is a test class that will indicate a proper or improper use. It can be replaced with a real unsafe object.

    public class UnsafeClass
    {
        long testValue = 0;
        int myInt = 5;

        public void Double()
        {
            if (Interlocked.CompareExchange(ref testValue, 1, 0) != 0)
                throw new ApplicationException("More then one method of UnsafeClass called simultaneously");

            myInt = myInt * 2;
            Thread.Sleep(100);

            Interlocked.Decrement(ref testValue);
        } 
    } 

    You may see we use Interlocked on a private class variable to make sure the method is running alone. And a Thread.Sleep to simulate a real action.

A wrapper

    So what do we really need. An object to lock on. An instance of out UnsafeClass. And a Queue of AutoResetEvent objects (Queue<AutoResetEvent>).

The class will look like this :

    public class SafeClassWrapper
    {
        UnsafeClass unsafeClass;
        Queue<AutoResetEvent> syncQueue;
        object syncRoot = new object();

        public SafeClassWrapper()
        {
            unsafeClass = new UnsafeClass();
            syncQueue = new Queue<AutoResetEvent>();
        }
    } 

 Now its time to wrap out methods with an Aync pattern. For example a mehod:

 public void Double()  
 Will be wrapped with:

 public IAsyncResult BeginDouble(AsyncCallback callback, object state) 
 public void EndDouble(IAsyncResult result) 

Read more: Codeproject

Posted via email from Jasper-net

0 comments: