Export (0) Print
Expand All

Interlocked.Decrement Method (Int32%)

Decrements a specified 32-bit signed integer variable and stores the result, as an atomic operation.

Namespace:  System.Threading
Assembly:  mscorlib (in mscorlib.dll)

public static int Decrement(
	ref int location
)

Parameters

location
Type: System.Int32%
The variable whose value is to be decremented.

Return Value

Type: System.Int32
The decremented value.

ExceptionCondition
ArgumentNullException

The address of location is a null pointer.

This method handles an overflow condition by wrapping: If location = Int32.MinValue, location - 1 = Int32.MaxValue. No exception is thrown.

The following example shows a thread-safe way to increment and decrement an integer value. The example defines CountClass, a class that keeps a running count of its instances by incrementing a counter in the constructor and decrementing the counter in the finalizer. Two counts are kept, one that uses standard addition and subtraction, and one that uses Increment and Decrement.

The example creates two threads, each of which creates and releases a large number of CountClass instances. After a garbage collection has been forced to clean up all the instances, both counts should be zero. SafeInstanceCount, which uses the Interlocked methods, will always be zero. However, UnsafeInstanceCount will not necessarily be zero because addition and subtraction are not atomic on fields: The count must be fetched, incremented, and then stored. A thread can be preempted in the middle of the increment or decrement operation — for example, after it has loaded and incremented the count, but before the new value has been stored. While the thread is preempted, the other thread can increment the count, or the finalizer thread can decrement the count. When the first thread continues running and stores its new value, it wipes out the operations that occurred while it was preempted. This program magnifies that effect because it does nothing but create instances, so that many instances of CountClass could be created while a thread is preempted.

In addition, on a multiprocessor computer two threads can be performing an operation simultaneously. Both can fetch the same value, increment it, and store it, so that the count is increased by one even though two instances are created.


using System;
using System.Threading;

class Example
{
   private static System.Windows.Controls.TextBlock outputBlock;


   public static void Demo(System.Windows.Controls.TextBlock outputBlock)
   {
      Example.outputBlock = outputBlock;
      Thread t = new Thread(DemoThreadProc);
      t.Start();
   }

   private static void DemoThreadProc()
   {
      // Start two threads that will create/destroy a large number of CountClass
      // objects, and block until the thread finish.
      Thread thread1 = new Thread(new ThreadStart(ThreadMethod));
      Thread thread2 = new Thread(new ThreadStart(ThreadMethod));
      thread1.Start();
      thread2.Start();
      thread1.Join();
      thread2.Join();

      // Have the garbage collector run the finalizer for each
      // instance of CountClass and wait for it to finish.
      GC.Collect();
      GC.WaitForPendingFinalizers();

      outputBlock.Dispatcher.BeginInvoke(delegate () {
          outputBlock.Text += String.Format(
             "After garbage collection has occurred for all instances of CountClass,\n" 
                 + "the instance count should be zero.\n\n" 
                 + "UnsafeInstanceCount: {0}\nSafeInstanceCount: {1}\n",
                        CountClass.UnsafeInstanceCount, 
                        CountClass.SafeInstanceCount); 
                                                     });
   }

   static void ThreadMethod()
   {
      CountClass cClass;

      // Create 100,000 instances of CountClass.
      for (int i = 0; i < 100000; i++)
      {
         cClass = new CountClass();
      }
   }
}

class CountClass
{
   static int unsafeInstanceCount = 0;
   static int safeInstanceCount = 0;

   static public int UnsafeInstanceCount
   {
      get { return unsafeInstanceCount; }
   }

   static public int SafeInstanceCount
   {
      get { return safeInstanceCount; }
   }

   public CountClass()
   {
      unsafeInstanceCount++;
      Interlocked.Increment(ref safeInstanceCount);
   }

   ~CountClass()
   {
      unsafeInstanceCount--;
      Interlocked.Decrement(ref safeInstanceCount);
   }
}

/* This example produces output similar to the following:

After garbage collection has occurred for all instances of CountClass,
the instance count should be zero.

UnsafeInstanceCount: -292
SafeInstanceCount: 0
 */


Silverlight

Supported in: 5, 4, 3

Silverlight for Windows Phone

Supported in: Windows Phone OS 7.1, Windows Phone OS 7.0

XNA Framework

Supported in: Xbox 360, Windows Phone OS 7.0

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.

Community Additions

Show:
© 2014 Microsoft