Export (0) Print
Expand All

Interlocked.Decrement Method (Int32)

Decrements a specified variable and stores the result, as an atomic operation.

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

'Declaration
Public Shared Function Decrement ( _
	ByRef location As Integer _
) As Integer

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 determines how many random numbers that range from 0 to 1,000 are required to generate 1,000 random numbers with a midpoint value. To keep track of the number of midpoint values, a variable, midpointCount, is set equal to 1,000 and decremented each time the random number generator returns a midpoint value. Because three threads generate the random numbers, the Decrement(Int32) method is called to ensure that multiple threads don't update midpointCount concurrently. Note that a lock is also used to protect the random number generator, and that a CountdownEvent object is used to ensure that the Main method doesn't finish execution before the three threads.

Imports System.Threading

Module Example
   Const LOWERBOUND As Integer = 0
   Const UPPERBOUND As Integer = 1001

   Dim lockObj As New Object()
   Dim rnd As New Random()
   Dim cte As CountdownEvent

   Dim totalCount As Integer = 0
   Dim totalMidpoint As Integer = 0
   Dim midpointCount As Integer = 10000

   Public Sub Main()
      cte = New CountdownEvent(1)
      ' Start three threads.  
      For ctr As Integer = 0 To 2
         cte.AddCount()
         Dim th As New Thread(AddressOf GenerateNumbers)
         th.Name = "Thread" + ctr.ToString()
         th.Start()
      Next
      cte.Signal()
      cte.Wait()
      Console.WriteLine()
      Console.WriteLine("Total midpoint values:  {0,10:N0} ({1:P3})",
                        totalMidpoint, totalMidpoint/totalCount)
      Console.WriteLine("Total number of values: {0,10:N0}", 
                        totalCount)                  
   End Sub 

   Private Sub GenerateNumbers()
      Dim midpoint As Integer = (upperBound - lowerBound) \ 2
      Dim value As Integer = 0
      Dim total As Integer = 0
      Dim midpt As Integer = 0
      Do 
         SyncLock lockObj
            value = rnd.Next(lowerBound, upperBound)
         End SyncLock 
         If value = midpoint Then 
            Interlocked.Decrement(midpointCount)
            midpt += 1
         End If
         total += 1    
      Loop While midpointCount > 0

      Interlocked.Add(totalCount, total)
      Interlocked.Add(totalMidpoint, midpt)

      Dim s As String = String.Format("Thread {0}:", Thread.CurrentThread.Name) + vbCrLf +
                        String.Format("   Random Numbers: {0:N0}", total) + vbCrLf +
                        String.Format("   Midpoint values: {0:N0} ({1:P3})", midpt, midpt/total)
      Console.WriteLine(s)
      cte.Signal()
   End Sub 
End Module 
' The example displays output like the following: 
'       Thread Thread2: 
'          Random Numbers: 3,204,021 
'          Midpoint values: 3,156 (0.099 %) 
'       Thread Thread0: 
'          Random Numbers: 4,073,592 
'          Midpoint values: 4,015 (0.099 %) 
'       Thread Thread1: 
'          Random Numbers: 2,828,192 
'          Midpoint values: 2,829 (0.100 %) 
'        
'       Total midpoint values:      10,000 (0.099 %) 
'       Total number of values: 10,105,805

The following example is similar to the previous one, except that it uses the task-based asynchronous pattern instead of a thread procedure to generate 50,000 random midpoint integers. In this example, a lambda expression replaces the GenerateNumbers thread procedure, and the call to the Task.WaitAll method eliminates the need for the CountdownEvent object.

Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Const LOWERBOUND As Integer = 0
   Const UPPERBOUND As Integer = 1001

   Dim lockObj As New Object()
   Dim rnd As New Random()

   Dim totalCount As Integer = 0
   Dim totalMidpoint As Integer = 0
   Dim midpointCount As Integer = 50000

   Public Sub Main()
      Dim tasks As New List(Of Task)()

      ' Start three tasks.  
      For ctr As Integer = 0 To 2
         tasks.Add( Task.Run(Sub() 
                                Dim midpoint As Integer = (upperBound - lowerBound) \ 2
                                Dim value As Integer = 0
                                Dim total As Integer = 0
                                Dim midpt As Integer = 0
                                Do 
                                   SyncLock lockObj
                                      value = rnd.Next(lowerBound, upperBound)
                                   End SyncLock 
                                   If value = midpoint Then 
                                      Interlocked.Decrement(midpointCount)
                                      midpt += 1
                                   End If
                                   total += 1    
                                Loop While midpointCount > 0

                                Interlocked.Add(totalCount, total)
                                Interlocked.Add(totalMidpoint, midpt)

                                Dim s As String = String.Format("Task {0}:", Task.CurrentId) + vbCrLf +
                                                  String.Format("   Random Numbers: {0:N0}", total) + vbCrLf +
                                                  String.Format("   Midpoint values: {0:N0} ({1:P3})", midpt, midpt/total)
                                Console.WriteLine(s)
                             End Sub ))
      Next
      Task.WaitAll(tasks.ToArray())
      Console.WriteLine()
      Console.WriteLine("Total midpoint values:  {0,10:N0} ({1:P3})",
                        totalMidpoint, totalMidpoint/totalCount)
      Console.WriteLine("Total number of values: {0,10:N0}", 
                        totalCount)                  
   End Sub 
End Module 
' The example displays output like the following: 
'       Task 1: 
'          Random Numbers: 24,530,624 
'          Midpoint values: 24,675 (0.101 %) 
'       Task 2: 
'          Random Numbers: 7,079,718 
'          Midpoint values: 7,093 (0.100 %) 
'       Task 3: 
'          Random Numbers: 18,284,617 
'          Midpoint values: 18,232 (0.100 %) 
'        
'       Total midpoint values:      50,000 (0.100 %) 
'       Total number of values: 49,894,959

.NET Framework

Supported in: 4.6, 4.5, 4, 3.5, 3.0, 2.0, 1.1

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

XNA Framework

Supported in: 3.0, 2.0, 1.0

Portable Class Library

Supported in: Portable Class Library

Supported in: Windows Phone 8.1

Supported in: Windows Phone Silverlight 8.1

Supported in: Windows Phone Silverlight 8
Show:
© 2015 Microsoft