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 Shared Function Decrement ( _
	ByRef location As Integer _
) As Integer


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

Return Value

Type: System.Int32
The decremented value.


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.

Imports System.Threading

Public Class Example

   Private Shared outputBlock As System.Windows.Controls.TextBlock

   Public Shared Sub Demo(ByVal outputBlock As System.Windows.Controls.TextBlock)

      Example.outputBlock = outputBlock
      Dim t As New Thread(AddressOf DemoThreadProc)

   End Sub

   Private Shared Sub DemoThreadProc()

      ' Start two threads that will create/destroy a large number of CountClass
      ' objects, and block until the thread finish.
      Dim thread1 As New Thread(AddressOf ThreadMethod)
      Dim thread2 As New Thread(AddressOf ThreadMethod)

      ' Have the garbage collector run the finalizer for each
      ' instance of CountClass and wait for it to finish.

      outputBlock.Dispatcher.BeginInvoke(displayHelper, _
          String.Format( _
             "After garbage collection has occurred for all instances of CountClass," & vbLf _
                 & "the instance count should be zero." & vbLf & vbLf _
                 & "UnsafeInstanceCount: {0}" & vbLf & "SafeInstanceCount: {1}", _
                        CountClass.UnsafeInstanceCount, _
   End Sub

   Private Shared Sub ThreadMethod()
      Dim cClass As CountClass

      ' Create 100,000 instances of CountClass.
      For i As Integer = 1 To 100000
         cClass = New CountClass()
      Next i
   End Sub

   ' Helper methods:

   ' In order to update the TextBlock object, which is on the UI thread, you must
   ' make a cross-thread call by using the Dispatcher object that is associated 
   ' with the TextBlock. The DisplayOutput helper method and its delegate, 
   ' displayHelper, are used by the BeginInvoke method of the Dispatcher object
   ' to append text to the TextBlock. 
   Private Shared displayHelper As New Action(Of String)(AddressOf DisplayOutput)
   Private Shared Sub DisplayOutput(ByVal msg As String)
      outputBlock.Text &= msg 
   End Sub

End Class

Public Class CountClass

   Shared unsafeCount As Integer = 0
   Shared safeCount As Integer = 0

   Shared ReadOnly Property UnsafeInstanceCount() As Integer
         Return unsafeCount
      End Get
   End Property

   Shared ReadOnly Property SafeInstanceCount() As Integer
         Return safeCount
      End Get
   End Property

   Sub New()
      unsafeCount += 1
   End Sub

   Protected Overrides Sub Finalize()
      unsafeCount -= 1
   End Sub

End Class

' 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: -305
'SafeInstanceCount: 0


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