Category: Technical

C#: lock vs Monitor

By Ashish Khandelwal, July 28, 2010

They both are same but each one has some draw back and advantages.

lock is more concise over monitor; it releases the lock from the blocked code even if there is exception generated within blocked code. There could be deadlock with lock if we do not use it correctly, also when we use lock the thread will wait for infinite time to get the lock on object.

On other hand Monitor has feature like ‘TryEnter’ and can wait for the lock for the given time so no infinite wait. With monitor the developer has to more careful about the code/logic to remove the lock using Exit (in both cases exception and normal). Possibility of error.

Normally lock is preferred over Monitor, but it is always developer call based upon the logic need.

VN:F [1.7.2_963]
Rating: 5.0/5 (1 vote cast)

C#: Thread Synchronization

By Ashish Khandelwal, July 27, 2010

This article describe .Net classes that can be used to synchronize access to resources in multithreaded applications.

One of the benefits of using multiple threads in an application is that each thread executes asynchronously. For Windows applications, this allows time-consuming tasks to be performed in the background while the application window and controls remain responsive. For server applications, multithreading provides the ability to handle each incoming request with a different thread. Otherwise, each new request would not get serviced until the previous request had been fully satisfied.

However, the asynchronous nature of threads means that access to resources such as file handles, network connections, and memory must be coordinated. Otherwise, two or more threads could access the same resource at the same time, each unaware of the other’s actions. The result is unpredictable data corruption.

For simple operations on integral numeric data types, synchronizing threads can be accomplished with members of the Interlocked class. For all other data types and non thread-safe resources, multithreading can only be safely performed using the constructs in this topic.

The lock Keyword

The lock keyword can be used to ensure that a block of code runs to completion without interruption by other threads. This is accomplished by obtaining a mutual-exclusion lock for a given object for the duration of the code block.

A lock statement begins with the keyword lock, which is given an object as an argument, and followed by a code block that is to be executed by only one thread at a time. For example:

public class TestThreading
{
private System.Object lockThis = new System.Object();
public void Function()
{
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
}

The argument provided to the lock keyword must be an object based on a reference type, and is used to define the scope of the lock. In the example above, the lock scope is limited to this function because no references to the object exist outside the function. Strictly speaking, the object provided to lock is used solely to uniquely identify the resource being shared among multiple threads, so it can be an arbitrary class instance. In practice, however, this object usually represents the resource for which thread synchronization is necessary. For example, if a container object is to be used by multiple threads, then the container can be passed to lock, and the synchronized code block following the lock would access the container. As long as other threads locks on the same contain before accessing it, then access to the object is safely synchronized.

Generally, it is best to avoid locking on a public type, or on object instances beyond the control of your application. For example, lock(this) can be problematic if the instance can be accessed publicly, because code beyond your control may lock on the object as well. This could create deadlock situations where two or more threads wait for the release of the same object. Locking on a public data type, as opposed to an object, can cause problems for the same reason. Locking on literal strings is especially risky because literal strings are interned by the common language runtime (CLR). This means that there is one instance of any given string literal for the entire program, the exact same object represents the literal in all running application domains, on all threads. As a result, a lock placed on a string with the same contents anywhere in the application process locks all instances of that string in the application. As a result, it is best to lock a private or protected member that is not interned. Some classes provide members specifically for locking. The Array type, for example, provides SyncRoot. Many collection types provide a SyncRoot member as well.

For more information on the lock keyword, see:

Monitors

Like the lock keyword, monitors prevent blocks of code from simultaneous execution by multiple threads. The Enter method allows one and only one thread to proceed into the following statements; all other threads are blocked until the executing thread calls Exit. This is just like using the lock keyword. In fact, the lock keyword is implemented with the Monitor class. For example:

lock (x)

{

DoSomething();

}

This is equivalent to:

System.Object obj = (System.Object)x;

System.Threading.Monitor.Enter(obj);

try

{

DoSomething();

}

finally

{

System.Threading.Monitor.Exit(obj);

}

Using the lock keyword is generally preferred over using the Monitor class directly, both because lock is more concise, and because lock insures that the underlying monitor is released, even if the protected code throws an exception. This is accomplished with the finally keyword, which executes its associated code block regardless of whether an exception is thrown.

For more information on monitors, see Monitor Synchronization Technology Sample.

Synchronization Events and Wait Handles

Using a lock or monitor is useful for preventing the simultaneous execution of thread-sensitive blocks of code, but these constructs do not allow one thread to communicate an event to another. This requires synchronization events, which are objects that have one of two states, signaled and un-signaled, that can be used to activate and suspend threads. Threads can be suspended by being made to wait on a synchronization event that is unsignaled, and can be activated by changing the event state to signaled. If a thread attempts to wait on an event that is already signaled, then the thread continues to execute without delay.

There are two kinds of synchronization events: AutoResetEvent, and ManualResetEvent. They differ only in that AutoResetEvent changes from signaled to unsignaled automatically any time it activates a thread. Conversely, a ManualResetEvent allows any number of threads to be activated by its signaled state, and will only revert to an unsignaled state when its Reset method is called.

Threads can be made to wait on events by calling one of the wait methods, such as WaitOne, WaitAny, or WaitAll. System.Threading.WaitHandle.WaitOne causes the thread to wait until a single event becomes signaled, System.Threading.WaitHandle.WaitAny blocks a thread until one or more indicated events become signaled, and System.Threading.WaitHandle.WaitAll blocks the thread until all of the indicated events become signaled. An event becomes signaled when its Set method is called.

In the following example, a thread is created and started by the Main function. The new thread waits on an event using the WaitOne method. The thread is suspended until the event becomes signaled by the primary thread that is executing the Main function. Once the event becomes signaled, the auxiliary thread returns. In this case, because the event is only used for one thread activation, either the AutoResetEvent or ManualResetEvent classes could be used.

using System;

using System.Threading;

class ThreadingExample

{

static AutoResetEvent autoEvent;

static void DoWork()

{

Console.WriteLine(”   worker thread started, now waiting on event…”);

autoEvent.WaitOne();

Console.WriteLine(”   worker thread reactivated, now exiting…”);

}

static void Main()

{

autoEvent = new AutoResetEvent(false);

Console.WriteLine(“main thread starting worker thread…”);

Thread t = new Thread(DoWork);

t.Start();

Console.WriteLine(“main thrad sleeping for 1 second…”);

Thread.Sleep(1000);

Console.WriteLine(“main thread signaling worker thread…”);

autoEvent.Set();

}

}

For more examples of thread synchronization event usage, see:

Mutex Object

A mutex is similar to a monitor; it prevents the simultaneous execution of a block of code by more than one thread at a time. In fact, the name “mutex” is a shortened form of the term “mutually exclusive.” Unlike monitors, however, a mutex can be used to synchronize threads across processes. A mutex is represented by the Mutex class.

When used for inter-process synchronization, a mutex is called a named mutex because it is to be used in another application, and therefore it cannot be shared by means of a global or static variable. It must be given a name so that both applications can access the same mutex object.

Although a mutex can be used for intra-process thread synchronization, using Monitor is generally preferred, because monitors were designed specifically for the .NET Framework and therefore make better use of resources. In contrast, the Mutex class is a wrapper to a Win32 construct. While it is more powerful than a monitor, a mutex requires interop transitions that are more computationally expensive than those required by the Monitor class. For an example of using a mutex, see Mutexes.

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

Volatile Keyword & Conclusion

By Ashish Khandelwal, July 26, 2010

In my previous articles on Thread Synchronization in .Net, we have discussed following Synchronization techniques:

In this article we will discuss on Volatile Keyword.

A Quick Word on the volatile Keyword

In your reading or study of .NET code, the volatile C# keyword might come up. This keyword does not exist in Visual Basic. Don’t worry though; it doesn’t add any functionality to C# that can’t be done with the other synchronization objects discussed in this case study.

The volatile keyword tells the compiler that the variable it references could change at anytime and that no optimizations should be done to it. It will prohibit the compiler from storing the variable in a register and force it read it new from memory each time.

Variables marked as volatile aren’t necessarily thread safe. They only insure that each read of the variable is the latest information. To see what a declaration looks like look at the following code snip-it, which declares an Integer variable as volatile.

private volatile int MyInteger;

Use of Monitor is a much safer and better way to handle synchronization. It guarantees that the variable is up to date as only one thread is accessing the variable at a time. It is safe to replace volatile variable access with Monitorblocks of code or any other synchronization method discussed in the case study that fit your needs. Good synchronization practice will eliminate the need for volatile.

Summary

Multithreaded applications are a must today.The Dot Net Framework makes creating these applications much easier than traditional programming methods. Be sure to take advantage of multithreading and of all available methods of synchronization.

When designing for multithreaded applications remember the age-old proverb: An ounce of prevention is worth a pound of cure. It is much easier to prevent deadlocks and other multithreaded bugs by taking a few extra minutes and trying to prevent them. You will usually spend a lot of time trying to find the cause of these bugs when reported from the field, as they don’t usually show up stepping through code, but only when running at full speed.

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

COM+ and Windows Forms Synchronization

By Ashish Khandelwal, July 26, 2010

In my previous articles on Thread Synchronization in .Net, we have discussed following Synchronization techniques:

In this article we will discuss on COM+ and Windows Forms Synchronization.

COM+ Synchronization

The .NET framework provides many enterprise services that can be used to build enterprise applications, one of which is the COM+ method of synchronization. COM+ offers developers many helpful techniques such as transaction handling between objects, loosely coupled events, object pooling and synchronization, which we will discuss here, to name a few. This synchronization method allows the usage of a concept called a context to provide ways to lock code for synchronization. This method can be implemented on any class that is derived from ContextBoundObject, or from any class that derives from ContextBoundObject.

When deriving a class from ContextBoundObject, the attribute <Syncronization()>can be used. This tells the runtime to provide synchronization for the entire class by making each class instance only accessible by one thread at a time. This case study will give a brief overview of this topic, as it is out of the scope of the article. Entire books have been written on the subject of COM+. For further reading on COM+ get a copy of Professional Visual Basic Interoperability – COM and VB6 to .NET, ISBN 1-861005-65-2.

When you use the attribute, COM+ will create a proxy for you that will run all instances of your object in its context. COM+ will marshal all calls across this proxy where a performance penalty occurs. The service guarantees that only one thread is available to run each object at a time.

Earlier the timed methods of the WaitHandle classes were discussed. Recall that the second parameter of the method was a boolean method that determined whether to release the synchronized context along with the object lock. If your classes use COM+ synchronization True should be passed for this parameter or deadlocks are risked. True tells COM+ to exit its synchronized context before the runtime allows the thread to wait. This allows other threads to then get access to the context avoiding deadlocks. If you don’t exit the context, the . Net runtime will allow other threads access to the locked object since an exit method has been called. When the next thread acquires a lock on the locking object it will then try to enter the context, which is still locked resulting in a deadlock.

While COM+ synchronization provides another easy way to provide synchronization, be careful when using it. Many calls to a COM+ synchronized object will degrade your application greatly because of all the marshaling across the proxy. Be sure to test responsiveness when using it.

Apartments and Window’s Form Synchronization

Now that we have examined all the methods that Visual Basic offers for synchronization, we will take a look at Window’s Form projects and what apartment threading is. The most common types of threading on the Windows platform are single threaded apartments (STA) or multithreaded apartments (MTA). Window’s forms must be hosted in an STA apartment because some Window’s Form controls are based on standard Windows COM controls that require an STA environment. Background threads can still be utilized to update forms, but synchronization must be done differently. As we examine the two apartment styles, we will look at how to do correct synchronization with Window’s Forms.

By default all Windows’ Form projects in Visual Basic are STA. Visual Basic applies the <STATHREAD()>attribute to the main entry point in the application for you behind the scenes. While you could override this attribute and change it to an MTA apartment, you should not or problems will occur with the COM controls as discussed above.

So what is an STA apartment?The apartment concept comes from the early COM days. Basically, STA means that only one thread can access an object, the thread that created it. Any future access to the object must also be done on the original thread. This is the one key reason why you should never update a control on a Window’s Form from another thread. Most COM objects require STA.

MTA, sometimes called free threading, is much harder to program than STA. This is another reason why we encounter STA COM components most of the time. MTA means that more than one thread can access an object at any given point in time safely. When programming for MTA, you must be sure to include good synchronization and design as discussed in the case study. Any number of threads could be accessing objects in your library at any time.

The type of threading model that the current thread is using can be determined simply with the following code.

Dim sThreadType As String
sThreadType = Thread.CurrentThread.ApartmentState.ToString()
MessageBox.Show(sThreadType)

sThreadType will equal “STA” or “MTA” after the call. There is also an ApartmentState object that can be set toThread.CurrentThread.AppartmentState().

Dim Apt as ApartmentState
Apt = Thread.CurrentThread.ApartmentState()
MessageBox.Show(apt.ToString())

Window’s Form classes provide built in methods to update GUI elements from other threads. These methods should be used exclusively. The methods are called InvokeBeginInvokeEndInvoke and CreateGraphics. All of the methods can be called from any thread. When called, the methods provide a way to work with the control from the main Window’s Form thread. Let’s see how we can use the methods.

The Invoke method takes a delegate for a parameter. A delegate is basically a variable that points to a method. The variable in this case tells the Invoke method what function to run. This delegate is run under the control’s owner thread and not the calling thread, preserving the STA style. Let’s take a look at a simple example that adds entries to a textbox control using a separate thread. A button and a multi-line textbox are added to a Window’s Form.

Private Sub btnStart_Click(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles btnStart.Click
    Dim Thread1 As Thread
    Thread1 = New Thread(AddressOf Thread1Work)
    Thread1.Start()
End Sub
Private Delegate Sub DelAddItem()
Private Sub Thread1Work()
    Dim del As DelAddItem
    del = New DelAddItem(AddressOf DelegateWork)
    txtList.Invoke(del)
    Console.WriteLine("Thread 1 Done")
End Sub
Private Sub DelegateWork()
    Dim i As Integer
    For i = 0 To 100
        txtList.Text = txtList.Text + "A New Line: " & i.ToString(+vbCrLf)
    Next 'i
    Console.WriteLine("Delegate Done")
End Sub

To call Invoke, a delegate sub is created. This sub simply adds a new line to the textbox with the words “A New Line”. When our new thread is started a new instance of the delegate is created. The new delegate is then passed totxtList. Invoke updating the text.

The Invoke method runs any code in the delegate synchronously on the thread. The output from the run will show this:

Delegate Done
Thread 1 Done

Thread 1 will not continue running until the delegate is finished.

Sometimes asynchronous calls are preferred. The BeginInvoke and EndInvoke allow updating the GUI using built in asynchronous technology in the framework. The two methods take the same delegate that Invoke did. They only call the code asynchronously. EndInvoke will return the resulting value from an asynchronous BeginInvoke call. If theBeginInvoke is still running, EndInvoke will block until the BeginInvoke call finishes. It will not terminate the BeginInvokecall. An example is below.

Private Sub btnStart_Click(ByVal sender As System.Object,
  ByVal e As System.EventArgs) Handles btnStart.Click
  Dim T hread1 As Thread
    Thread1 = New Thread(AddressOf Thread1Work)
    Thread(1.Start())
End Sub
Private Delegate Sub DelAddItem()
Private Sub Thread1Work()
    Dim del As DelAddItem
    Dim Result As IAsyncResult
    del = New DelAddItem(AddressOf DelegateWork)
    Result = txtList.BeginInvoke(del)
    Console.WriteLine("Thread 1 Done")
    Console.WriteLine(Result.IsCompleted.ToString())
    txtList.EndInvoke(Result)
    Console.WriteLine(Result.IsCompleted.ToString())
End Sub
Private Sub DelegateWork()
    Dim i As Integer
    For i = 0 To 100
        txtList.Text = txtList.Text + "A New Line: " & i.ToString(+vbCrLf)
    Next 'i
    Console.WriteLine("Delegate Done")
End Sub

Output:

Thread 1 Done
False
Delegate Done
True

As we see from the output, Thread 1 completed before the delegate finished. Then the first call to Result.IsCompletedreturns false, signifying that the delegate is still running. Thread 1 is then put to sleep with the EndInvoke call allowing the delegate time to finish. The next call to Result.IsCompleted returns true.

The code also shows two methods of getting the status of an asynchronous call. The first method was the line Result = txtList.BeginInvoke(del). The Result variable will contain the current results of the asynchronous call. The other method is with the EndInvoke call, which we said earlier, would block until the asynchronous call is finished. The last output of true shows that this behavior happened.

When using graphics drawing methods with Window’s Forms you must be sure to do all work on the main thread also. The CreateGraphics method makes sure of this for you. It can be called from other threads safely like the invoke methods. The Graphics object returned will run all calls in the correct thread for you. The Graphics object is considered thread safe so no additional locking objects are necessary.

In my next article i have covered following Thread Synchronization techniques:

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

ReaderWriterLock Object

By Ashish Khandelwal, July 26, 2010

In my previous articles on Thread Synchronization in .Net, we have discussed following Synchronization techniques:

In this article we will discuss on ReaderWriterLock Object.

Many times, you read data much more often than you write it. Traditional synchronization can be overkill in these situations as it would lock resources when threads are reading or writing to the resource. A more efficient way has been added to the framework to handle this. The ReaderWriterLock is a synchronization class that allows multiple threads to read a variable, but only one thread to write to it at a time.

When acquiring a lock, the write thread must also wait until all reader threads have unlocked the object before obtaining an exclusive write lock. All readers will then be blocked until the writer thread releases its lock. The power of the class comes from the fact that it will allow multiple reader locks to access the resource at the same time. We will look first at how to acquire reader locks on an object.

Dim lData As Long = 1
Dim objLock As ReaderWriterLock
Private Sub btnRun_Click(ByVal sender As System. Object, _
  ByVal e As System. EventArgs) Handles btnRun.Click

    Dim Thread1 As Thread
    Dim Thread2 As Thread
    objLock = New ReaderWriterLock()
    Thread1 = New Thread(AddressOf Thread1Work)
    Thread2 = New Thread(AddressOf Thread2Work)
    Thread1.Start()
    Thread2.Start()
End Sub
Private Sub Thread1Work()
    Dim i As Integer
    For i = 1 To 10
        objLock.AcquireReaderLock(1000)
        Console.WriteLine(lData & " Thread 1")
        Thread.Sleep(10)
        objLock.ReleaseReaderLock()
    Next
End Sub
Private Sub Thread2Work()
    Dim i As Integer
    For i = 1 To 10
        objLock.AcquireReaderLock(1000)
        Console.WriteLine(lData & " Thread 2")
        objLock.ReleaseReaderLock()
    Next
End Sub

We create an instance of a ReaderWriterLock object called objLock. Then two threads are spawned, both of which do a quick loop that writes the value of lData to the console window ten times. The first thread also has a ten-millisecond sleep call. This allows us to see that the second thread continues to get a reader lock on objLock even though the first already has one. Note also that we have passed a millisecond time limit to the methods. You must pass a timeout value to AcquireReaderLock. If you wish to wait infinitely, use the constant Timeout. Infinite.

The output should be something similar to the following:

1 Thread 1
1 Thread 2
1 Thread 2
1 Thread 2
1 Thread 2
1 Thread 2
1 Thread 2
1 Thread 2
1 Thread 2
1 Thread 2
1 Thread 2
1 Thread 1
1 Thread 1
1 Thread 1
1 Thread 1
1 Thread 1
1 Thread 1
1 Thread 1
1 Thread 1
1 Thread 1

This shows that the second thread ran while the first had a ReaderLock on the lData integer.

If needed, there is also a method IsReaderLockHeld that will return true if the current thread already has a reader lock. This helps keep track of multiple locks by one thread. For each call to AcquireReaderLock a subsequent call toReleaseReaderLock is required. If you do not call ReleaseReaderLock the same number of times, the reader lock is never fully released, never allowing a write to the resource. IsReaderLockHeld can be checked to see if a reader lock is already active on the thread, and if so not acquire another one.

Now let’s examine how to update the variable. A writer lock can be obtained by calling AcquireWriterLock. Once all reader locks have been released, the method will obtain an exclusive lock on the variable. When updating the variable, all reader threads will be locked out until ReleaseWriterLock is called. Let’s examine the code for this.

Dim lData As Long = 1
Dim objLock As ReaderWriterLock
Private Sub btnRun_Click(ByVal sender As System. Object, _
  ByVal e As System.EventArgs) Handles btnRun.Click
    Dim Thread1 As Thread
    Dim Thread2 As Thread
    Dim Thread3 As Thread
    objLock = New ReaderWriterLock()
    Thread1 = New Thread(AddressOf Thread1Work)
    Thread2 = New Thread(AddressOf Thread2Work)
    Thread3 = New Thread(AddressOf Thread3Work)
    Thread1.Start()
    Thread2.Start()
    Thread3.Start()
End Sub
Private Sub Thread1Work()
    Dim i As Integer
    For i = 1 To 10
        objLock.AcquireReaderLock(1000)
        Console.WriteLine(lData & " Thread 1")
        Thread.Sleep(100)
        objLock.ReleaseReaderLock()
    Next
End Sub
Private Sub Thread2Work()
    Dim i As Integer
    For i = 1 To 10
        objLock.AcquireReaderLock(1000)
        Console.WriteLine(lData & " Thread 2")
        Thread.Sleep(100)
        objLock.ReleaseReaderLock()
    Next
End Sub
Private Sub Thread3Work()
    objLock.AcquireWriterLock(Timeout.Infinite)
    lData = 2
    Console.WriteLine("Thread 3 updated lData")
    objLock.ReleaseWriterLock()
End Sub

You will notice that we have added a new thread, Thread3 and a function for it to run. This new function acquires a writer lock on the object and then updates lData to 2. The first two threads, Thread1 and Thread2, are put to sleep for one hundred milliseconds to allow thread three to start. When examining the output from this code, you will see that thread three waits until threads one and two release their locks. This thread three updates the variable. Thread one and two must then wait on it. As with the reader lock, there is also a method called IsWriterLockHeld that will return true if the current thread has a writer lock. You should get output similar to below:

1 Thread 1
1 Thread 2
Thread 3 updated lData
2 Thread 2
2 Thread 1
2 Thread 2
2 Thread 1
2 Thread 2
2 Thread 1
2 Thread 2
2 Thread 1
2 Thread 2
2 Thread 1
2 Thread 2
2 Thread 1
2 Thread 2
2 Thread 1
2 Thread 2
2 Thread 1
2 Thread 2
2 Thread 1

Another useful method of the ReaderWriterLock class is the UpgradeToWriterLock method. This method allows a reader lock to become a writer lock to update the data. Sometimes it is useful to check the value of a data item to see if it should be updated. Acquiring a writer lock to check the variable is wasted time and processing power. By getting a reader lock first other reader threads are allowed to continue accessing the variable until you determine an update is needed. Once the update is needed, UpgradeToWriterLock is called locking the resource for update as soon as it can acquire the lock. Just like AcquireWriterLockUpgradeToWriterLock must wait until all readers accessing the resource are done. Now let’s look at the code.

Dim lData As Long = 1
Dim objLock As ReaderWriterLock
Private Sub btnRun_Click(ByVal sender As System.Object, _
  ByVal e As System. EventArgs) Handles btnRun.Click
    Dim Thread1 As Thread
    Dim Thread2 As Thread
    objLock = New ReaderWriterLock()
    Thread1 = New Thread(AddressOf Thread1Work)
    Thread2 = New Thread(AddressOf Thread2Work)
    Thread1.Start()
    Thread2.Start()
End Sub
Private Sub Thread1Work()
    Dim i As Integer
    For i = 1 To 10
        objLock.AcquireReaderLock(1000)
        If lData = i Then
            objLock.UpgradeToWriterLock(Timeout.Infinite)
            lData = i + 1
            Console.WriteLine("lData is now " & lData)
        End If
        Thread.Sleep(20)
        objLock.ReleaseReaderLock()
    Next
End Sub
Private Sub Thread2Work()
    Dim i As Integer
    For i = 1 To 10
        objLock.AcquireReaderLock(1000)
        Console.WriteLine(lData & " Thread 2")
        Thread.Sleep(20)
        objLock.ReleaseReaderLock()
    Next
End Sub

In this example, we have changed thread one to examine the value of lData after acquiring a reader lock. If the value oflData is equal to the looping variable of i (which it always is in our example) then it tries to obtain a writer lock by calling UpgradeToWriterLock. Nothing special is required to release the writer lock once finished with it. The normalReleaseReaderLock will release the upgraded writer lock, or calling DowngradeFromWriterLock can be used also which will be discussed next. The output should be something similar to the following:

lData is now 2
2 Thread 2
lData is now 3
3 Thread 2
lData is now 4
4 Thread 2
lData is now 5
5 Thread 2
lData is now 6
6 Thread 2
lData is now 7
7 Thread 2
lData is now 8
8 Thread 2
lData is now 9
9 Thread 2
lData is now 10
10 Thread 2
lData is now 11
11 Thread 2

Opposite of UpgradeToWriterLock we can also use DowngradeFromWriterLock. Like its name suggests the method will make a writer lock turn to a reader lock. To use the function, you must pass it a LockCookie. This cookie can be generated from UpgradeToWriterLock. Because of the LockCookie requirement, you may only useDowngradeFromWriterLock on the same thread that UpgradeToWriterLock is called.

One advantage of DowngradeFromWriterLock is that the call returns immediately and will not block the thread at all. This happens because it can only be called from a thread that has a writer lock on an object. This means that no other thread can have a lock; hence the method knows that it is the only thread active on the object. If read access is still required to the resource this method will eliminate the need to reacquire a read lock on the thread. If read access is not required anymore, simply use ReleaseReaderLock as shown above. Let’s examine some code now.

Dim lData As Long = 1
Dim objLock As ReaderWriterLock
Private Sub btnRun_Click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles btnRun.Click
    Dim Thread1 As Thread
    Dim Thread2 As Thread
    objLock = New ReaderWriterLock()
    Thread1 = New Thread(AddressOf Thread1Work)
    Thread2 = New Thread(AddressOf Thread2Work)
    Thread1.Start()
    Thread2.Start()
End Sub
Private Sub Thread1Work()
    Dim i As Integer
    Dim objCookie As LockCookie
    For i = 1 To 10
        objLock.AcquireReaderLock(1000)
        If lData = i Then
  objCookie = objLock.UpgradeToWriterLock(Timeout. Infinite)
            lData = i + 1
            Console.WriteLine("lData is now " & lData)
            objLock.DowngradeFromWriterLock(objCookie)
            Console.WriteLine("Downgraded lock")
        End If
        Thread.Sleep(20)
        objLock.ReleaseReaderLock()
    Next
End Sub
Private Sub Thread2Work()
    Dim i As Integer
    For i = 1 To 10
        objLock.AcquireReaderLock(1000)
        Console.WriteLine(lData & " Thread 2")
        Thread.Sleep(20)
        objLock.ReleaseReaderLock()
    Next
End Sub

The only differences in this code from the UpgradeToWriterLock are the lines:

objCookie = objLock.UpgradeToWriterLock(Timeout. Infinite)

And

objLock.DowngradeFromWriterLock(oCookie)
Console.WriteLine("Downgraded lock")

Instead of just waiting until the ReleaseReaderLock is called, we explicitly change the writer lock to a reader lock. The only real difference between downgrading and releasing the lock are with any other waiting writer locks. If you downgrade and still have waiting writer locks, they must continue to wait until the downgraded lock is released. You should see output similar to the following:

1 Thread 2
lData is now 2
Downgraded lock
2 Thread 2
lData is now 3
Downgraded lock
3 Thread 2
lData is now 4
Downgraded lock
4 Thread 2
lData is now 5
Downgraded lock
5 Thread 2
lData is now 6
Downgraded lock
6 Thread 2
6 Thread 2
lData is now 7
Downgraded lock
7 Thread 2
lData is now 8
Downgraded lock
8 Thread 2
lData is now 9
Downgraded lock
9 Thread 2
lData is now 10
Downgraded lock
lData is now 11

Downgraded lock

Two other methods of note on the ReaderWriterLock class are ReleaseLock and RestoreLockReleaseLock immediately drops all locks that the current thread holds. It returns a LockCookie just like UpgradeToWriterLock that can be used inRestoreLock. When used, the LockCookie returns the thread back to the exact lock state that it held before. To handle the fact that other threads could have acquired locks on the object, the method will block until it can resolve all of its previous locks. The code is as follows:

Dim oLock As ReaderWriterLock
Private Sub btnRun_Click(ByVal sender As System.Object, ByVal _
  e As System.EventArgs) Handles btnRun.Click
    Dim Thread1 As Thread
    Dim objCookie As LockCookie
    objLock = New ReaderWriterLock()
    Thread1 = New Thread(AddressOf Thread1Work)
    objLock.AcquireWriterLock(Timeout.Infinite)
    Thread1.Start()
    Thread.Sleep(1000)
    objCookie = objLock.ReleaseLock
    Thread1 = New Thread(AddressOf Thread1Work)
    Thread1.Start()
    Thread.Sleep(1000)
    objLock.RestoreLock(oCookie)
    Thread.Sleep(1000)
    Thread1 = New Thread(AddressOf Thread1Work)
    Thread1.Start()
End Sub
Private Sub Thread1Work()
    Try
        objLock.AcquireReaderLock(10)
        Console.WriteLine("Got a reader lock")
        objLock.ReleaseReaderLock()
    Catch
        Console.WriteLine("Reader lock not held")
    End Try
End Sub

Examining the code, we first see that a writer lock is acquired. Thread1 is then started to show that it can’t acquire a reader lock on the object. The main thread then releases the writer lock by calling ReleaseLock and saving its state toobjCookie.Thread1 is then restarted acquiring the reader lock. A call to RestoreLock is called then with the LockCookiepassed to it. When thread one is restarted at that point it cannot acquire its reader lock. The call to RestoreLock has replaced the writer lock on the object. The output looks like the following:

Reader lock not held
Got a reader lock
Reader lock not held

Another interesting pair of functions in the ReaderWriterLock class is the function WriterSeqNum andAnyWritersSince.WriterSeqNum returns the sequence number of the current lock in the internal queue of theReaderWriterLock class. This queue keeps the order of the threads that have requested reader or writer locks on an object. AnyWritersSince will tell if any writer locks have been released since the call to WriterSeqNum. This is a good method to check if a piece of data has been updated on another thread. AnyWritersSince could be used in a large, time-consuming report situation. If no writers have updated the report data then there is no need to recalculate the report. The following code will show the methods in action.

Dim objLock As ReaderWriterLock
Private Sub btnRun_Click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles btnRun.Click
    Dim objCookie As LockCookie
    Dim SeqNum As Integer
    Dim Thread1 As Thread
    objLock = New ReaderWriterLock()
    Thread1 = New Thread(AddressOf Thread1Work)
    objLock.AcquireWriterLock(Timeout.Infinite)
    SeqNum = objLock.WriterSeqNum
    If objLock.AnyWritersSince(SeqNum) = False Then
        Console.WriteLine("We see that no writers have released yet")
    End If
    objLock.ReleaseWriterLock()
    Thread1.Start()
    Thread1.Join()
    If objLock.AnyWritersSince(SeqNum) = True Then
        Console.WriteLine("We see that a writer has released now")
    End If
End Sub
Public Sub Thread1Work()
    objLock.AcquireWriterLock(Timeout.Infinite)
    objLock.ReleaseWriterLock()
End Sub

First a writer lock is acquired on objLock. The sequence number is saved in SeqNum. Then a test to AnyWritersSince is made. Since no other threads have acquired any writer locks and released them, the method returns false. Next a thread, Thread1, is started and waited on. This thread simply acquires a writer lock and releases it. The main thread then checks AnyWritersSince again using the saved off sequence number. Since another thread has released a writer lock the method return true this time. The following output is returned.

We see that no writers have released yet
We see that a writer has released now

In my next article i have covered following Thread Synchronization techniques:

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

Mutex Class

By Ashish Khandelwal, July 26, 2010

In my previous articles on Thread Synchronization in .Net, we have discussed following Synchronization techniques:

The next class in our list, Mutex, can be thought of as a more powerful version of Monitor. Like AutoResetEvent andManualResetEvent, it is derived from WaitHandle. An advantage of Mutex over Monitor is that you can use the methods from WaitHandle such as WaitOne. A disadvantage is that is much slower, at about half as fast as MonitorMutex is very useful when you must control access to a resource that could be accessed through multiple processes, like a data file used by several applications you have created. To write to the file, the writing thread must have total access to the file throughout the operating system.

When you create a Mutex, you can assign it a name. If the name exists anywhere in the operating system then thatMutex object instance will be returned. This is the reason why Mutex is slower, also. The system must be checked to see if the Mutex already exists. If it doesn’t exist, a new one is created. When the last thread in the operating system that references the named Mutex terminates, the Mutex is destroyed. The following code example shows how to use aMutex to control access to a file.

Our first program:

Dim mutexFile As Mutex
Private Sub btnSetMutex_Click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles btnSetMutex.Click
    mutexFile = New Mutex(False, "Mutex Name")
    mutexFile.WaitOne()
    'do some file manipulation here such as write to it
    'For demonstration purposes we will release
    'the mutex in another button click
End Sub
Private Sub btnRelease_Click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles btnRelease.Click
    mutexFile.ReleaseMutex()
End Sub

Our Second Program

Private Sub btnAquireMutex_Click(ByVal sender As _
  System.Object, ByVal e As System.EventArgs) Handles
    btnAquireMutex.Click()
    Dim mutexFile As Mutex
    mutexFile = New Mutex(False, "Mutex Name")
    mutexFile.WaitOne() 'Wait until the file is open
    Console.WriteLine("Mutex was released from another process")
    'Now I know that I have explicit access to the file
    'I can write to it now.
    mutexFile.ReleaseMutex()
End Sub

Let’s examine the first program. A Mutex called mutexFile is created. Internally to the operating system, we name the mutex “Mutex Name”. This is the name that will be used to resolve any other calls to the same mutex from any other application that we create. On a form we have two buttons. For demonstration purposes, one button will acquire a lock on the resource, in this case the file, using the Mutex and the other button will release the lock. This simulates a long running process on the file. As with the other synchronization classes, you should make sure to call RelaseMutexsometime after a lock is acquired or a block on the resource will occur.

The second program is very straightforward. We create a Mutex object called fileMutex making sure we have named it the same as in the first program, “Mutex Name”. If this is not done the Mutex classes will refer to different mutexes in the operating system. Then WaitOne is called without a timeout value. This will make the thread wait until the Mutexhas been released. When the release button is clicked in the first program, the second can continue running since it can now acquire access to the resource. Mutex was released from another process is printed in the output window. You can also close the first program and the lock will be released. When a thread exits that has a Mutex lock on a resource, ReleaseMutex is automatically called for you.

In summary, remember that Monitor should be used most of the time. It is faster than a MutexMutex should only be used when you need to synchronize across multiple processes to gain access to a common resource among several programs that you have written. Even though Mutex allows for the wait methods where Monitor does not, the otherWaitHandle classes should be considered before Mutex if you need the wait methods first.

In my next article i have covered following Thread Synchronization techniques:

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

WaitHandle, AutoResetEvent and ManualResetEvent Classes

By Ashish Khandelwal, July 26, 2010

In my previous article on Thread Synchronization in .Net, we have discussed following Synchronization techniques:

In this article we will examine a MustInherit type class, WaitHandleWaitHandle provides a class definition for three other classes, MutexManualResetEvent and AutoResetEvent, and provides means for your own objects to inherit synchronization functionality. These objects allow threads to wait until classes derived from WaitHandle are signaled. The WaitHandle derived classes add functionality over Monitor in that threads can be programmed to wait until multiple classes are signaled. Of course, along with more power and flexibility comes more work and chance of problems.

The two reset event classes can be used in context with Mutex to provide similar functionality to Monitor. The major difference between Mutex and Monitor is that Mutex can be used across processes. You can think of the two reset event classes as being switches. The thread cannot enter a Mutex unless its object is signaled. We will examine them in detail next.

The AutoResetEvent class can be compared to the Monitor. Pulse method. Imagine it as a tollbooth. Each car has to pay to go through, the signal, and then the gate closes behind the car when it passes making the next car in line pay again. The AutoResetEvent class is like this. It automatically goes back to unsignaled after being signaled and a thread goes through, just like Monitor. PulseManualResetEvent can be described as a water hose, once open it lets everything through until you close it yourself.

Let’s examine the AutoResetEvent in detail first. It comes equipped with two methods to control its state, Set andReset. Set allows one thread to acquire the lock on the object. After allowing a thread to pass through, Reset will automatically be called, returning the state to unsignaled.

On the first call to Set the runtime will make sure that the state of the object is signaled. Multiple calls to Set have no effect if the state is already signaled, and it will still allow only one thread to pass. You do not know the order of threads for each signal either. If multiple threads are waiting on an object, you are only guaranteed that one will get in per Set when a wait method is called.

Reset can be used to change the state of the object back to unsignaled from signaled before a thread calls a wait method on the object. Reset will return True if it can change the state back to unsignaled or False if it can not. It has no effect on an unsignaled object. The code below will show how an AutoResetEvent works.

Dim WaitEvent As AutoResetEvent
  WaitEvent = New AutoResetEvent(False)
Public Sub DoWork()
    'do some long processing task simulate by sleeping
    Thread.Sleep(5000)
    WaitEvent.Set()
End Sub
Public Sub Thread2()
    'we want thread 2 to run after thread1 is
    'finished. It will take
    'the data computed by thread 1 and do
    'something to it
    WaitEvent.WaitOne() 'Wait until DoWork is done and the
    'WaitEvent is signaled
    'wait until thread 1 is done to keep going
End Sub

In the above code, we make a new instance of an AutoResetEvent. Our main thread then would call DoWork while a secondary thread would call Thread2. When the secondary thread reached the WaitOne call, it would enter theWaitSleepJoin state until the main thread calls the Set method after its long processing task allowing Thread2 to continue execution. When DoWork calls WaitEvent.Set() it signals that it is available for another thread that is waiting to obtain continue running. Since our Thread2 is waiting, it continues now.

To fully understand the AutoResetEvent class, we must also examine the WaitHandle class. AutoResetEvent is derived from WaitHandle. It inherits several methods at which we will look at.

The first method, WaitOne, we have already seen in action in the above code sample. Basically, it will wait until the object has become signaled. WaitOne without any parameters will wait infinitely until the object becomes signaled. There are also several overrides that allow you to wait for an amount of time, both in milliseconds or a TimeSpan. If time elapses on these methods, WaitOne will return false indicating that a lock couldn’t be obtained.

The timed methods of WaitOne also take a boolean parameter that is worthy of note. If you pass false to the parameter, nothing different happens from calling the standard no parameter WaitOne except for the timeout. If true is passed, and WaitOne is called from a COM+ synchronized context, it will force the thread to exit the context before waiting. This method won’t affect your code unless you use the COM+ methods of synchronization, which we will discuss later.

The next method, WaitAll, is very useful when you have a large amount of work to accomplish and want to use multiple threads to accomplish it. This allows a thread to wait on multiple objects. Once all objects in the array are signaled the waiting thread is allowed to continue execution.

As with the WaitOne method, the no parameter method waits indefinitely while two other methods exist to wait for a specific amount of time. The method also has the boolean parameter for exiting a synchronized context. Be careful when waiting infinitely when using WaitAll. If you don’t signal all instances of the AutoResetEvent correctly as shown below, your waiting thread will never resume.

Lets take a look at a code example of how to use WaitAll. First the form’s code:

Dim WaitAllEvents(1) As AutoResetEvent
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim thread1 As Thread
    Dim thread2 As Thread
    'first we create 2 threads as assign them to subs
    thread1 = New Thread(AddressOf Thread1Work)
    thread2 = New Thread(AddressOf Thread2Work)

    'Next our 2 AutoRresetEvent instances are created
    WaitAllEvents(0) = New AutoResetEvent(False)
    WaitAllEvents(1) = New AutoResetEvent(False)
    thread1.Start()
    thread2.Start()
    'after starting the threads we tell the main thread to
    'wait until all instances of AutoResetEvent have become
    'signaled with a call to Set()
    WaitHandle.WaitAll(WaitAllEvents)
    Console.WriteLine("All threads done exiting main thread")
    thread2 = Nothing
    thread1 = Nothing
End Sub
Private Sub Thread1Work()
    Thread.Sleep(5000)
    Console.WriteLine("Thread1 done")
    WaitAllEvents(0).Set() 'I’m done so signal my Event
End Sub
Private Sub Thread2Work()
    Thread.Sleep(3000)
    Console.WriteLine("Thread2 done")
    WaitAllEvents(1).Set() 'I’m done so signal my Event
End Sub

Now some code in a Module.

<MtaThread()> Public Sub Main()
    Dim frm As Form1
    frm = New Form1()
    frm.ShowDialog()
End Sub

The output from the code is:

Thread2 Done
Thread1 Done
All threads done exiting main thread

As you can see from the output the main thread waits until all objects in its WaitAllEvents array are signaled. Another item that is worthy to note here is the attribute <MTATHREAD()>. This signifies that the main thread should run as a multithreaded apartment style thread and not as a single threaded apartment, which is the default. WaitAll must be called from a thread that is an MTAThread. If not it will throw a NotSupportedException. While done as an example above with a simple WinForm, you should not run your main thread that opens Window’s Forms on an MTAThread. This will cause some problems with some of the controls.

The single threaded apartment style thread model guarantees that only one thread is accessing code at one time. In order for Windows Forms projects to work correctly, they must be run in a single threaded apartment. This does not mean than worker threads cannot be created and used. We will go into more detail about Windows Form synchronization later in the case study. Some of the other project types, such as the Window’s service project, are by default multithreaded apartments. The MTA style will also be discussed later. In these situations, WaitAll can be used very effectively.

The last method we will examine is WaitAny. This method waits until any one object in the array is signaled. An example of its use could be a dictionary search engine. The program could start two threads, the first that started with the letter A and the second that started with the letter Z. The first match found by either thread will terminate the others that are searching and return control to the main application. The return of this method tells you the position of the array that was signaled. Like the other two methods, you can wait indefinitely or for a specific amount of time.

Let’s look at a code example.

Dim WaitAnyEvents(1) As AutoResetEvent
Private Sub Start_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
  Handles Button1.Click
    Dim Thread1 As Thread
    Dim Thread2 As Thread
    Thread1 = New Thread(AddressOf Thread1Work)
    Thread2 = New Thread(AddressOf Thread2Work)
    WaitAnyEvents(0) = New AutoResetEvent(False)
    WaitAnyEvents(1) = New AutoResetEvent(False)
    Thread1.Start()
    Thread2.Start()
    WaitHandle.WaitAny(WaitAnyEvents)
    Console.WriteLine("One thread done exiting main thread")
End Sub
Private Sub Thread1Work()
    Thread.Sleep(5000)
    Console.WriteLine("Thread1 done")
    WaitAnyEvents(0).Set()
End Sub
Private Sub Thread2Work()
    Thread.Sleep(3000)
    Console.WriteLine("Thread2 done")
    WaitAnyEvents(1).Set()
End Sub

In examining the above code, we see that an array of AutoResetEvent has been created as a form level variable so that all subroutines can access it. We have put a command button on the form. This button is the main worker of the example. When it is clicked, we create two new threads and assign their individual subs to run upon starting. The subs simulate work by sleeping for a while. When done sleeping, a string is out put to the debug window and the corresponding AutoResetEvent is signaled. This causes the main thread to resume running. You should receive the following output from the example:

Thread2 Done
One thread done exiting main thread
Thread1 done

The output shows that the main thread resumes running after the first object has been released. Because the main thread doesn’t abort the first thread, Thread1, it eventually finishes outputting its string “Thread1 done”. If the other threads are no longer needed they should be aborted manually from your main thread with a call to Abort.

Now let’s examine a way to signal an event and have it stay signaled, the ManualResetEvent. This event will stay signaled no matter how many threads do a wait method on it. This only way to change the state is to call Reset. You can use the object to control access to data that multiple threads are waiting on. For example, we might have two threads or more, we might not know (or care), waiting on a piece of data that another thread is calculating. When this thread gets done with its work, we can let all other threads in to access the data. At some later time if we determine that the data needs to be recalculated, we can turn off the threads from accessing it. Then do our new calculations.

Let’s look at some code now.

Private ManualWaitEvent As ManualResetEvent
Dim Thread1 As Thread
Dim sData As String
Private Sub Form1_Load(ByVal sender As System.Object, _
  ByVal e As System. EventArgs) Handles MyBase.Load
    ManualWaitEvent = New ManualResetEvent(False)
    Thread1 = New Thread(AddressOf ReadWork)
    Thread1.IsBackground = True
    Thread1.Start()
End Sub
Private Sub ReadWork()
    'this method will wait until ManualWaitEvent is
    'signaled
    Dim i As Integer
    For i = 0 To 100
        ManualWaitEvent.WaitOne()
        Console.WriteLine(sData & i.ToString())
        Thread.Sleep(1000)
    Next 'i
End Sub
Private Sub btnSet_Click(ByVal sender As System.Object, ByVal _
  e As System.EventArgs) Handles btnSet.Click
    sData = "Work Done: "
    ManualWaitEvent.Set()
End Sub
Private Sub btnReset_Click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles btnReset.Click
    ManualWaitEvent.Reset()
End Sub

When the form loads, we create a new instance of a ManualResetEvent in the unsignaled state. A thread is created and started. The thread then waits until the event becomes signaled. When signaled it reads a string that we are using to represent our data. This is a very powerful method of controlling synchronization when you have multiple threads. It lets you fine tune access to variables easily. You can easily switch on and off access to the data.

Every second, the thread will output “Work Done: “ and the value of i until the ManualWaitEvent is unsignaled by pressing the reset button. If the set button is pressed again the thread will resume its work and continue to output data to the output window. Every time ManualWaitEvent. WaitOne() is called, a check of the state of ManualWaitEventis done. If this call were outside of the loop, all one hundred values of i would have been printed the first time the set button was pressed.

Also note the IsBackground call in the form load event. This makes Thread1 a child thread to the main process thread. If the main thread is terminated, the operating system will also terminate any background threads related to the main one. If the thread were not a background thread, it would continue running until it was finished, even when we closed our main thread out. If the state of ManualWaitEvent were unsignaled, the thread would be waiting on an object that could never be signaled again since our main form was gone. This results in the process being left in memory. This should be avoided by making all threads background threads, unless it is 100% necessary for the thread to finish regardless of the state of the application. Make sure that these non-background threads have access to any resources they need also. If termination of the main running program disposes of a needed resource, the thread will never finish or result in an error.

In my next article i have covered following Thread Synchronization techniques:

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

Thread Synchronization in .Net

By Ashish Khandelwal, July 26, 2010

In this article i will discuss about various thread synchronization techniques available in .Net.

What is thread synchronization?

Imagine the following lines of code:

Dim X as Integer
X = 1
X = X + 1

To a programmer the line X = X + 1 is a single operation. But consider this line from a computer’s perspective. Computers use machine language, which could mean many separate operations for each line of code. For example the line above could be broken down in to several operations, such as:Move the value of X into a register, move the value 1 into another register, add the two registers and place the value into a third register and finally move the added values into the memory address of the variable X.

Imagine the above situation with multiple threads trying to access the variable X at the same time. Synchronization is the process of eliminating these kinds of errors. Without synchronization programming, the computer could stop the first thread at any point in time, and let the second access the variable. If the second thread was incrementing X by 1 also, it might finish, and then the computer resumes the original thread that was running. This thread would restore its variable information, replacing the new X with the old value, nullifying the work that the second thread accomplished. This is called a race condition. These errors are very hard to find. It is best to put time in preventing them. .

To synchronize code, you utilize locks. A lock is a way to tell the computer that the following group of code should be executed together as a single operation, and not let other threads have access to the resource that is locked until the locking code is finished. In the case study, we will examine the different types of locks and objects that allow locking, and discuss when to use each method. When your code can handle multiple threads, safely, it is considered thread safe. This common term is used on code libraries and controls to designate that they are compatible with multiple threads.

Synchronization also adds a new type of bug you have to watch out for, deadlocking. Deadlocking can occur if you aren’t careful with your locking techniques. For example, assume that we have two resources, A and B. Thread 1 calls and locks resource A at the same time thread 2 calls and locks resource B. Thread 1 then requests resource B and thread 2 requests resource A. This is called a deadlock. Thread 1 can’t release resource A until it gets resource B, and thread 2 can’t release resource B until it gets A. Nothing happens and your system can’t ever complete either of the two threads. Needless to say this is very bad.

The only way to avoid deadlocks is to never allow a situation that could create one. Code both threads to allocate resources in the same order. Have thread 1 allocate A and then B, and the same with thread 2. This way thread 2 will never start until thread 1 is finished with resource A. Then it will wait until thread 1 is finished with resource B before continuing, and avoid the deadlock. Another good practice is to lock resources as late as possible. Try to avoid getting locks until you absolutely need them and then release them as soon as possible. Next we shall take a look at all the different methods of thread synchronization that the common language runtime provides.

Interlocked Class

Because it is a very common programming technique, variable increment and decrement have their own framework class, the Interlocked class. This class provides simple thread safe methods to do some common tasks with variables. The Increment and Decrement methods add or subtract 1 from a variable. These methods can be considered “atomic”. This means that the operating system will consider the entire operation as one not allowing other threads to interrupt their execution. The class is a member of System.Threading. To use the functions without fully qualifying the name, add an Imports System.Threading line. I will assume that the System. Threadingnamespace has been imported for all examples in the case study.

Dim X as Integer
X = 1
X = Interlocked.Increment(X)
X = Interlocked.Decrement(X)

The above code ensures that the computer will not interrupt the increment or decrement of the variable X.

There are two additional methods in the Interlocked class, Exchange and CompareExchange. Let’s take a closer look at the two. The Exchange method replaces the value of a variable with the value supplied. The second value could be a hard coded value or a variable. Don’t let the name of the method, Exchange, confuse you though. Only the first variable passed in the first parameter will be replaced by the second. The method won’t really exchange the values of two variables.

Dim X as Integer = 5
Dim Y as Integer = 1
Interlocked.Exchange(X, Y)‘X now equals 1 Y is still 1
Interlocked.Exchange(X, 4) ‘X now equals 4

CompareExchange will do a comparison of two variables, and if equal, replace the one used as the first parameterwith the supplied value.

Dim i As Integer
i = 200
Interlocked.CompareExchange(i, DateTime. Now. Day, 200)

The above code creates a new integer and then assigns the value 200 to it. We then call theInterlocked.CompareExchange. The method compares the variable i with 200 and since they are the same, it will replace i with DateTime. Now. Day, the current day of the month.

The Interlocked class allows you to do basic programming techniques and make them thread safe. Let’s examine how to do more than just basic commands now. The Dot Net framework provides several classes, and Visual Basic. Net provides one method to handle complete synchronization. First we will take a look at the SyncLock Visual Basic.Net keyword.

SyncLock Keyword

The SyncLock keyword (lock in C#) gives an easy way to quickly lock parts of code. It is a built in keyword in Visual Basic. Net now. Take a look at the following code segment:

Dim sText as String
  Dim objLock as Object = New Object()
  SyncLock objLock
  sText = “Hello”
End SyncLock

First we declare a new string, sText. Then we set up a SyncLock block to control access to the object using another locking object, objLock. This guarantees that only one thread at a time can set the object to the string “Hello”. A lock object must be used or an exception will be thrown on the Exit call. If you try to use an object that has changed since the Enter call, the Exit will fail, so you cannot lock on sText itself. The most common use of SyncLock is to lock the entire object it is in by using the Me keyword as the parameter of the SyncLock. This will lock the object for all threads except the executing one. This provides a very high degree of control over the locking patterns of the object at the cost of flexibility.

Public Sub Foo()
  Dim sText as String
  SyncLock Me
    sText= “Hello”
  End SyncLock
End Sub

Locking the entire object is usually a great waste of time and processing power. Other methods in the Me object that have locking code based on the Me object won’t be accessible to any threads while in the lock. If a more flexible approach is needed, a locking variable can be used. Locks can also only be obtained on reference types. If a lock on a value type is needed, you must use a locking object as shown below. The code locks access to iData via a reference type, System. Object. Imagine the locking object as a key to the code. Only one thread at a time can have the key. This allows for much greater control over what gets locked. This method will also not lock the whole Me object. Other threads are free to access other methods of Me, which is much more efficient and will reduce the possibility of deadlocks.

Public Sub Foo()
  Dim iData as Integer
  Dim objLock as Object = New Object()

  SyncLock objLock
   iData = 3
  End SyncLock
End Sub

One drawback to using SyncLock is that other threads must wait forever for the lock to be released if they need the locked resource. They will never time out. If you aren’t careful and enter an infinite loop in the locking thread, or hog resources, you can easily create deadlocks or periods of time where nothing happens. In later sections, better methods of synchronization will be discussed.

Flow control statements such as GoTo cannot move the code flow into a SyncLock block of code. The thread must execute the SyncLock keyword. Old Visual Basic 6 error handling cannot be used from inside a SyncLock block either since it uses exception handling internally. Since all new code should be written with exception handling, you probably won’t run into a situation like this unless upgrading a legacy application. I would highly recommend rewriting any legacy error handling even if the methods aren’t used for multithreading. Neither of the following code blocks will compile:

SyncLock Me
  On Error GoTo Errhandle 'won't compile
  Dim i As Integer
  i = 5
End SyncLock
Exit Sub
Errhandle:

Or:

GoTo EnterHere 'won't compile
SyncLock Me
  EnterHere:
  Dim i As Integer
  i = 5
End SyncLock

In the next section we will examine how SyncLock works internally.

Monitor Class

To examine how SyncLock works, we have to explore a framework class, the Monitor class. The Monitor class does exactly what it says: monitors the access to a region of code and prevents multiple threads from entering. If you are familiar with win32 programming using C++, Monitor is similar to a critical section. Monitor creates a lock on an object that doesn’t allow any other threads to obtain access to the object until released by the locking thread. These locks are on sections of memory, hence the common name critical section. We will first see how to control access to a block of code, just like with the SyncLock keyword.

The Enter function of the Monitor class works just like the SyncLock keyword and the Exit function is like the End Synclock keywords. Internally SyncLock uses the Monitor class to implement its functionality and generates the innerTry Finally block of the code sample for you. Let’s look at the code now:

Public Sub Foo()
    Dim sText As String
    Dim objLock As Object = New Object()
    Try
        Monitor.Enter(objLock)
        Try
            sText = "Hello"
        Finally
            Monitor.Exit(objLock)
        End Try
    Catch e As Exception
        MessageBox.Show(e.Message)
    End Try
End Sub

This provides the exact same functionality that the SyncLock example above did. You will also notice that the Exit is contained in the finally clause of a Try Catch Finally block. This is to ensure that Exit gets called so the thread won’t get locked infinitely. Monitor. Enter is also called outside of the Try Catch Finally block. This is so Monitor. Exitwon’t get called if the Enter method doesn’t, as it will throw another exception. So why should we use Monitor, as theSyncLock keyword provides the same functionality without the extra work of Monitor. We will examine the reasons whyMonitor should be used as we look at the other methods of Monitor.

We said earlier that the SyncLock block would wait indefinitely on the executing thread to release the lock. The Monitorclass provides a much better method to handle this, the TryEnter method. This is the first reason why you would useMonitor over SyncLock. This method will allow the calling thread to wait a specific amount of time to acquire a lock before returning false and stopping its execution. This allows graceful handling of long running threads or deadlocks. If a deadlock has occurred, you certainly do not want to add more threads that are trying to get to the deadlocked resource.

The default method of no parameters, will try to acquire a lock, and if unsuccessful it will return false immediately. There are also two additional overloads that will wait for the specific number of milliseconds, or the specifiedTimeSpan. This offers much more flexibility than SyncLock.

Public Sub Foo()
    Dim sText As String
    Dim objLock As Object = New Object()
    Dim bEnteredOk As Boolean

    bEnteredOk = Monitor.TryEnter(objLock, 5000)
    If bEnteredOk = True Then
        sText = "Hello"
        Monitor.Exit(objLock)
    End If
End Sub

This example will try to acquire a lock for five seconds. If successful the stringis set to “Hello”.

The rest of Monitor’s methods must be examined together. The SyncLock keyword and the Monitor. Enter rely on putting waiting threads to sleep to stop their execution. This isn’t the best practice to follow as there is no way to get them to stop waiting unless aborted. The Monitor. Wait and Monitor. Pulse allow threads to wait on other conditions before starting. The methods will place the thread in a wait state allowing other threads to specify when they need the waiting thread to run. An example of this is a queue. You could have a thread that waits in an idle state until other threads place objects in the queue for it to work on.

To use the methods you first tell a thread to wait on an object with a Monitor. Wait call like below.

Public Sub fred()
    Dim objLock As Object = New Object()
    Dim bPulsed As Boolean
    Monitor.Enter(objLock)
    bPulsed = Monitor.Wait(objLock)
    If bPulsed Then
        'thread was pulsed
    End If
    Monitor.Exit(objLock)
End Sub

The thread is automatically unlocked with the Wait call. You must be sure to call Monitor. Exit when the thread is pulsed and done with its work, or you will have a block that could result in a deadlock. The first thread will wait until the pulsing thread has released its lock. This will make the thread wait until a Monitor. Exit is called, like the following.

Monitor.Enter(objLock)
Monitor.Pulse(objLock)
Monitor.Exit(objLock)

If the Exit call is left off a block occurs because the waiting thread cannot obtain its lock on the object that the pulsing thread has. You must also use the same object to lock on, and pulse from the second thread that the waiting thread used to wait on, objLock. Also, both Wait and Pulse must be called from a locked block of code, hence the Enter andExit calls in the above code. You should exit immediately after calling Pulse to allow the first thread to perform its work, since the pulsing code has the current lock on objLock.

The Monitor class also comes equipped with a PulseAll method. Unlike Pulse, which will only start the next waiting thread, PulseAll removes the wait state from all waiting threads and allows them to continue processing. As with thePulse method, PulseAll must be called from a locked block of code, and on the same object that the original threads are waiting on.

The Monitor class will provide for most of your threading synchronization needs. It should be used unless a more specific task calls for the next few classes we will examine. Here is a review of some good practices to follow when using Monitor:

  1. Exit MUST be called the same number of times Enter is called, or a block will occur.
  2. Make sure that the object used to call Enter is the same object that is used to call Exit or the lock will not be released.
  3. Don’t call Exit before calling Enter, or call Exit more times than calling Enter or an exception will occur.
  4. Place the Exit method call in a Finally block. All code that you wish to lock should be in the Try section of the corresponding Finally block. The Enter call should be in its own Try block. This eliminates calling Exit if theEnter fails.
  5. Don’t call Enter on an object that has been set to Nothing or an exception will occur.
  6. Don’t change the object that you use as the locking object, which brings in 7,
  7. Use a separate locking object, and not the changing object. If you use an object that has changed, an exception will be generated.

MethodImplAttribute

Code attributes in the Dot Net Framework can sometimes make programming easier. The MethodImplAttribute is one example of the hundreds of different attributes that you can use. It is in the System. Runtime. CompilerServicesnamespace. This attribute is particularly interesting to synchronization because it can synchronize an entire method with one simple command.

If you place the attribute before a function and supply the MethodImplOptions. Synchronized enumeration in the constructor, the entire method will be synchronized when called. The compiler will create output that wraps the whole function, MySyncMethod, in a Monitor. Enter and Monitor. Exit block. When a thread starts to enter the method it will acquire a lock. Upon exiting the method, it will release the lock. Here is an example of using the attribute.

<MethodImplAttribute(MethodImplOptions.Synchronized)>Private
Sub MySyncMethod()
End Sub

This attribute should only be used when an entire function needs to be synchronized, so it is rarely used. If you can exit the synchronized block of code before the end of the method or wait to enter it to the middle of the method, Monitorshould be used, as the attribute would waste processing cycles by locking the whole method and not just what needs to be synchronized.

Please follow below links for related Thread Synchronization techniques:

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

Multithreading

By Ashish Khandelwal, July 26, 2010

Definition of Threads

In order to understand multithreading we first have to understand threads. Each application/program that is running on a system is a process. The process for each program consists of one or more threads that are given processor time to do the work. Each thread contains all of the context information required by the system in order to execute the program instructions.

The operating system is responsible for scheduling and execution of threads. Remember the days of Windows 3.x? A single process thread could, and usually did, monopolize all of the processor time. The system would just sit and wait for the thread to complete prior to executing any other processes.

Newer operating systems, such as Windows 2000, support pre-emptive multitasking which allocates each thread a time slice. When the time slice of the currently executing thread has elapsed, the thread is suspended by the operating system, context of the thread is saved, context of another thread is loaded, and the other thread then resumes execution according to its previous state. This gives the appearance that multiple threads are executing at the same time and helps prevent the system from becoming unresponsive from a single thread (end task anyone?). On systems that have more that one processor threads are distributed across all of the processors so there really are multiple threads executing at the same time.

Threading Model Background

There are many threading models available and a lot of theory behind them. I do not claim to be an expert on any threading model, nor am I going to attempt to explain them in depth in this article. However, we will focus on the threading models that are common to the Microsoft Win32 based environments, and I’ll provide brief explanation about each.

Single Threaded

Single threaded means there is only one thread within the process and it is doing all of the work for the process. The process must wait for the current execution of the thread to complete before it can perform another action.

Single threaded results in system idle time and user frustration. For example, assume we are saving a file to a remote network using a single threaded application. Since there is only a single thread in the application, the application will not be able to do anything else while the file is being stored in the remote location. Thus the user waits and begins to wonder if the application is ever going to resume.

Apartment Threading (Single Threaded Apartment)

Apartment threaded means there are multiple threads within the application. In single threaded apartment (STA) each thread is isolated in a separate apartment underneath the process. The process can have any number of apartments that share data through a proxy. The application defines when and for how long the thread in each apartment should execute. All requests are serialized through the Windows message queue such that only a single apartment is accessed at a time and thus only a single thread will be executing at any one time. STA is the threading model that most Visual Basic developers are familiar with because this is the threading model available to VB applications prior to VB.NET. You can think of it like an apartment building full of a row of one room apartments that are accessible one at a time through a single hallway. The advantage this provides over single threaded is that multiple commands can be issued at one time instead of just a single command, but the commands are still sequentially executed.

Free Threading (Multi Threaded Apartment)

Free threaded applications were limited to programming languages such as C++ until the release of Microsoft .NET. The free threaded/Multi Threaded Apartment (MTA) model has a single apartment created underneath the process rather than multiple apartments. This single apartment holds multiple threads rather than just a single thread. No message queue is required because all of the threads are a part of the same apartment and can share data without a proxy. You can think of it like a building with multiple rooms that are all accessible once you are inside the building. These applications typically execute faster than single threaded and STA because there is less system overhead and can be optimized to eliminate system idle time.

These types of applications are more complex to program. The developer must provide thread synchronization as part of the code to ensure that threads do not simultaneously access the same resources. A condition known as a race condition can occur when a thread accesses a shared resource and modifies the resource to an invalid state and then another thread accesses the shared resource and uses it in the invalid state before the other thread can return the resource to a valid state. Therefore it is necessary to place a lock on a resource to prevent other threads from accessing the resource until the lock has been removed. However, this can lead to a deadlock situation where two threads are competing for resources and neither can proceed. For example, thread #1 has a resource locked and is waiting for another resource that is currently locked by thread #2. Thread #2 happens to be waiting for the resource locked by thread #1. Thus, both threads are waiting on the other and neither will be allowed to proceed. The only way to avoid situations like these is through good design and testing.

Using Multiple Threads

There are advantages and disadvantages to the use of multiple threads. Using multiple threads is not always advantageous, so you should make the determination for yourself whether or not there is enough benefit for your application(s).

Advantages of Multiple Threads

  • Improved responsiveness — When it comes to application performance I am a firm believer that perception is reality. If the user perceives that my application is slow, then it that means it is in reality slow. If the application is performing operations that take a perceivably long time to complete, these operations can be put into a separate thread which will allow the application to continue to be responsive to the user.
  • Faster application — Multiple threads can lead to improved application performance. For example, if there are a number of calculations to be performed or the contents of a file are being processed, then there the application can be made faster by performing multiple operations at the same time.
  • Prioritization — Threads can be assigned a priority which would allow higher priority tasks to take precedence over lower priority tasks.

Disadvantages of Multiple Threads

  • Programming and debugging is more complex — With multithreaded applications the programmer must account for race conditions and deadlocks.
  • Threads add overhead to the system — In order for the operating system to track a large number of threads it is going to consume processor time. If there are too many threads then each thread may not be given enough time to execute during its time slice. In addition, each thread is scheduled for execution less frequently due to the volume and time slice committed to each thread.
VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

Can I Use Visual Studio 2003 or the .NET Framework 1.1 to Create Generics?

By Ashish Khandelwal, July 25, 2010

Unfortunately no. Generics are only supported on version 2.0 and above of the Microsoft .NET framework. Code that relies on generics must run on version 2.0 of the CLR. Because of the way the CLR version unification works, a run-time process can only load a single version of the CLR. Consequently, a process that loaded version 1.1 of the CLR cannot use generic types. If you must use generic types from .NET 1.1, you can use the following work-around: First, wrap the generic types with object-based types (at the expense of course of the benefits of using generics). Next, load the wrapper classes in a separate process which loads version 2.0 of the CLR, and provide remote access to the wrapper classes to legacy clients in process that use version 1.1 of the CLR. For remote communication you can use any number of cross-process communication mechanisms, such as Remoting, Enterprise Services, sockets, etc.

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

Can I Use Generics in .NET Remoting?

By Ashish Khandelwal, July 25, 2010

Yes. You can expose generic types as remote objects, for example:

public class MyRemoteClass<T> : MarshalByRefObject
{...}
Type serverType = typeof(MyRemoteClass<int>);

RemotingConfiguration.RegisterWellKnownServiceType(serverType,
                                                   "Some URI",
                                                  WellKnownObjectMode.SingleCall);

Note that the specific type arguments used must be a marshalable type, that is, either serializable or derived from MarshalByRefObject. Consequently, a generic remote type will typically place a derivation constraint from MarshalByRefObject on its generic type parameters when expecting reference type parameters:

public class MyRemoteClass<T> : MarshalByRefObject where T : MarshalByRefObject
{...}

To administratively register a generic type, provide the type arguments in double square brackets.

For example, to register the class MyRemoteClass<T> with an integer, you should write:

<service>
   <wellknown type="MyRemoteClass[[System.Int32]],ServerAssembly"
              mode="SingleCall" objectUri="Some URI"/>
</service>

The double square brackets is required in case you need to specify multiple type arguments, in which case, each type arguments would be encased in a separate pair of brackets, separated by a comma. For example, to register the class MyRemoteClass<T,U> with an integer and a string, you would write:

<service>
   <wellknown type="MyRemoteClass[[System.Int32],[System.String]],
                     ServerAssembly" mode="SingleCall" objectUri="Some URI"/>
</service>

Creating a new instance of generic remote objects is done just as with non-generic remote objects.

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

Can I Use Generics in Web Services?

By Ashish Khandelwal, July 25, 2010

Unfortunately, no. Web services have to expose a WSDL-based contract. Such contracts are always limited by the expressiveness of the message format being used. For example, HTTP-GET based web services only support primitive types such as int or string, but not complex types like a DataSet. SOAP-based web services are more capable, but SOAP has no ability to represent generic type parameters. As a result, at present, you cannot define web services that rely on generic types. That said, you can define .NET web services that rely on closed constructed generic types, for example:

public class MyWebService
{
   [WebMethod]
   public List<string> GetCities()
   {
      List<string> cities = new List<string>();
      cities.Add("New York");
      cities.Add("San Francisco");
      cities.Add("London");
      return cities;
   }
}

In the above example, List<string> will be marshaled as an array of strings.

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

Which Versions of the .NET Framework Support Generics?

By Ashish Khandelwal, July 25, 2010

Generics are only supported on version 2.0 and above of the Microsoft .NET framework, as well as version 2.0 of the compact framework.

Refer: http://msdn.microsoft.com/en-us/library/aa479866.aspx

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

C#: Generic Enum

By Ashish Khandelwal, July 25, 2010

The problem

A common problem in any application is to present a user-friendly list of options in a drop down list, while for processing or storage convenience, an enum or other set of constants is used by the application code to indicate the permissible values, and an enum or integer would be used to store it.

Ever since I first started using C#, I’ve solved this problem by creating an enum to contain the constants, and if they need to be presented to a user for selection, a description class, with at least two properties for a text representation and the enum value itself. When using data binding, I’ve also found it convenient to supply a further property which provides a conversion of the enum to either intshort, or byte depending upon the bound fields type, but more about that later. To create the list, I usually build a static array of this class and then assign it as the data source of a drop down list in the presentation layer.

The solution

The sample code creates a small Windows application which demonstrates creating a list, binding it to a drop down list, and displays the enum and integer values of the selected list item. The combo box is bound to an array of class ExampleDetails which is accessed using a static property of that class, the DisplayMember property being bound to the Text property and the ValueMember being bound to the detail property. When the user selects a list item, the value of the SelectedValue property is displayed (the enum) as is the integer equivalent by accessing the underlying object using the SelectedItem property.

This code is implemented in the SelectedItemChanged event, the following code shows the important bits from that event. The Text property of a couple of labels are set with the use of the string.Format method, the first label just displays the value of the SelectedValue property which will be the enum since that’s what ValueMember is set to. Below that, I use the as operator to cast the SelectedItem to an ExampleDetailsobject. It’s worth pointing out that the as operator is very useful, it casts an object to the indicated class, but if it can’t, it sets the variable to nullrather than throwing an InvalidCastException, and you can then test the variable for null. I tend to use it more than a regular cast. Following the cast, the second label is populated with a string showing the integer value of the enum.

// display the enum value

label2.Text = string.Format( "Enum value: {0}",
                     cbExample.SelectedValue );

// get the details object 

ExampleDetails details =
       cbExample.SelectedItem as ExampleDetails;

// and display the integer value

label3.Text = string.Format( "Integer value: {0:n0}",
                                     details.value );

Here’s the ExampleDetails class:

public class ExampleDetails : EnumDetails<ExampleEnum> {

    public ExampleDetails( string text, ExampleEnum detail )
      : base( text, detail ) {
    }

    /// <summary>

    /// An array describing each of the enum values

    /// </summary>

    public static ExampleDetails[] details {

      get {
        return new ExampleDetails[] {
          new ExampleDetails("First", ExampleEnum.exOne),
          new ExampleDetails("Second", ExampleEnum.exTwo),
          new ExampleDetails("Third", ExampleEnum.exThree)
        };
      }
    }
}

ExampleDetails inherits from the Generic class EnumDetails. The enum ExampleEnum is declared as the type parameter in angled brackets alongside the EnumDetails declaration, to indicate that this is the class that the Generic template should ‘swap’ in.

In order to pass the correctly typed data down to the base class, a constructor is created which takes the text representation of the enum (‘First’ for instance) and a value of type ExampleEnum, these parameters are passed down to the base class by calling the base constructor which, thanks to the Generic declaration, will now be expecting a string and an ExampleEnum. The static property provides an array ExampleDetails which contains the descriptive text for the enum value and the value itself.

I should point out that you don’t have to inherit EnumDetails, you could create a class which creates and supplies an array ofEnumDetails<ExampleEnum>, that would work and there’s nothing wrong with it. But I prefer to inherit, mostly because I think it’s more object oriented. By creating the ExampleDetails class, I have a class whose sole responsibility is to supply a detail list of itself for the ExampleEnum.

Here’s the EnumDetails class, well, part of it anyway:

  public class EnumDetails<T> where T : struct {

    private string fText;
    private T fEnum;

    public EnumDetails( string text, T detail ) {
      fText = text;
      fEnum = detail;
    }

    /// <summary>

    /// Description of the enum value

    /// </summary>

    public string text {

      get {
        return fText;
      }
    }

    /// <summary>

    /// The value itself

    /// </summary>

    public T detail {

      get {
        return fEnum;
      }
    }

EnumDetails is the Generic base class, the important thing to note here is the <T> type parameter in the class declaration. What this does is inform the compiler that the class is Generic, and that where T appears in the code, it should be replaced with the type specified in the implementation of the class. Thus, for the ExampleDetails implementation, ExampleEnum is declared as the type T, so anywhere in EnumDetails where T is declared is ‘swapped’ for ExampleEnum. Hence, the constructor will only accept an ExampleEnum value for the detail parameter and will then store it in thefEnum member variable.

Another useful feature of Generics is the ability to constrain the type T to a particular type or one of its descendants, that’s what the ‘where T :struct‘ declaration is doing. Unfortunately, since my aim was to supply textual representations of enums, I’d have really liked to be able to constrain on enum, but you can’t, the closest is struct which is arguably better as it covers the numeric types as well.

  /// <summary>

    /// The enum value converted to an integer

    /// </summary>

    public int value {

      get {
        return Convert.ToInt32(fEnum);
      }
    }

    /// <summary>

    /// The enum value converted to a short

    /// </summary>

    public short shortValue {

      get {
        return Convert.ToInt16(fEnum);
      }
    }

    /// <summary>

    /// The enum value converted to a byte

    /// </summary>

    public byte byteValue {

      get {
        return Convert.ToByte( fEnum );
      }
    }

EnumDetails also declares three other properties, valueshortValue, and byteValue, they serve an interesting purpose. I do a lot of database programming, thus what I declare as an enum in the code may well be an intsmallint, or tinyint column in the database (if the database is SQL Server). If I create a typed dataset, these columns will be declared in the dataset as an intshort, or byte. When binding to one of these columns in a dropdown list, it is no use setting the ComboBox ValueMember to the enum property, the binding will never work. This is because the types are incompatible, by that I mean that a given enum value (which may well equal one in memory) will never equal the same value expressed as an intunless one of them is cast to the other type (i.e. intValue == (int)enumValue). But if I set the ComboBox ValueMember to the valueproperty, since it converts the enum to an int, the binding will match the values correctly and display the correct selection in the ComboBox.

Conclusion

The EnumDetails class is a simple implementation of Generics, but I’m sure that if I add it to a code library and reference it in my projects, it will end up saving me a lot of time. That’s because in using EnumDetails, implementing this kind of list will now be a very trivial exercise that will take only a few minutes to complete. Also, each implementation of EnumDetails helps to test it, so with each successive implementation, I can be more confident that the implementation will work first time. And that is what code reuse is all about.

VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)

C#: Generic Method

By Ashish Khandelwal, July 25, 2010

The goal of Generic Method is to build a swap method that can operate on any possible data type (value-based or reference-based) using a single type parameter. Due to the nature of swapping algorithms, the incoming parameters will be sent by reference (via the C# ref keyword). Here is the full implementation:

// This method will swap any two items.
// as specified by the type parameter <T>.
static void Swap<T>(ref T a, ref T b)
{
   Console.WriteLine("You sent the Swap() method a {0}",
      typeof(T));
   T temp;
   temp = a;
   a = b;
   b = temp;
}

Notice how a generic method is defined by specifying the type parameter after the method name but before the parameter list. Here, you’re stating that the Swap() method can operate on any two parameters of type <T>. Just to spice things up a bit, you’re printing out the type name of the supplied placeholder to the console using the C# typeof() operator. Now ponder the following Main() method that swaps integer and string types:

static void Main(string[] args)
{
   Console.WriteLine("***** Fun with Generics *****\n");
   // Swap 2 ints.
   int a = 10, b = 90;
   Console.WriteLine("Before swap: {0}, {1}", a, b);
   Swap<int>(ref a, ref b);
   Console.WriteLine("After swap: {0}, {1}", a, b);
   Console.WriteLine();

   // Swap 2 strings.
   string s1 = "Hello", s2 = "There";
   Console.WriteLine("Before swap: {0} {1}!", s1, s2);
   Swap<string>(ref s1, ref s2);
   Console.WriteLine("After swap: {0} {1}!", s1, s2);
   Console.ReadLine();
}
VN:F [1.7.2_963]
Rating: 0.0/5 (0 votes cast)