Interlocked.Decrement Methode

Definition

Dekrementiert den Wert einer angegebenen Variablen und speichert das Ergebnis in einer atomaren Operation.

Überlädt

Decrement(Int32)

Dekrementiert den Wert einer angegebenen Variablen und speichert das Ergebnis in einer atomaren Operation.

Decrement(Int64)

Dekrementiert den Wert der angegebenen Variablen und speichert das Ergebnis in einer atomaren Operation.

Decrement(UInt32)

Dekrementiert den Wert einer angegebenen Variablen und speichert das Ergebnis in einer atomaren Operation.

Decrement(UInt64)

Dekrementiert den Wert einer angegebenen Variablen und speichert das Ergebnis in einer atomaren Operation.

Decrement(Int32)

Dekrementiert den Wert einer angegebenen Variablen und speichert das Ergebnis in einer atomaren Operation.

public:
 static int Decrement(int % location);
public static int Decrement (ref int location);
static member Decrement : int -> int
Public Shared Function Decrement (ByRef location As Integer) As Integer

Parameter

location
Int32

Die Variable, deren Wert dekrementiert werden soll.

Gibt zurück

Int32

Der dekrementierte Wert.

Ausnahmen

Die Adresse von location ist ein null-Zeiger.

Die Adresse von location ist ein null-Zeiger.

Beispiele

Im folgenden Beispiel wird bestimmt, wie viele Zufallszahlen, die zwischen 0 und 1.000 liegen, erforderlich sind, um 1.000 Zufallszahlen mit einem Mittelwert zu generieren. Wenn Sie die Anzahl der Mittelwertwerte nachverfolgen möchten, midpointCountwird eine Variable auf 1.000 festgelegt und jedes Mal erhöht, wenn der Zufallszahlengenerator einen Mittelwert zurückgibt. Da drei Threads die Zufallszahlen generieren, wird die Decrement(Int32) Methode aufgerufen, um sicherzustellen, dass mehrere Threads nicht gleichzeitig aktualisiert werden midpointCount . Beachten Sie, dass eine Sperre auch verwendet wird, um den Zufallszahlengenerator zu schützen, und dass ein CountdownEvent Objekt verwendet wird, um sicherzustellen, dass die Main Methode die Ausführung nicht vor den drei Threads beendet.

using System;
using System.Threading;

public class Example
{
   const int LOWERBOUND = 0;
   const int UPPERBOUND = 1001;
   
   static Object lockObj = new Object();
   static Random rnd = new Random();
   static CountdownEvent cte;
   
   static int totalCount = 0;
   static int totalMidpoint = 0;
   static int midpointCount = 10000;

   public static void Main()
   {
      cte = new CountdownEvent(1);
      // Start three threads. 
      for (int ctr = 0; ctr <= 2; ctr++) {
         cte.AddCount();
         Thread th = new Thread(GenerateNumbers);
         th.Name = "Thread" + ctr.ToString();
         th.Start();
      }
      cte.Signal();
      cte.Wait();
      Console.WriteLine();
      Console.WriteLine("Total midpoint values:  {0,10:N0} ({1:P3})",
                        totalMidpoint, totalMidpoint/((double)totalCount));
      Console.WriteLine("Total number of values: {0,10:N0}", 
                        totalCount);                  
   }

   private static void GenerateNumbers()
   {
      int midpoint = (UPPERBOUND - LOWERBOUND) / 2;
      int value = 0;
      int total = 0;
      int midpt = 0;
      
      do {
         lock (lockObj) {
            value = rnd.Next(LOWERBOUND, UPPERBOUND);
         }
         if (value == midpoint) { 
            Interlocked.Decrement(ref midpointCount);
            midpt++;
         }
         total++;    
      } while (Volatile.Read(ref midpointCount) > 0);
      
      Interlocked.Add(ref totalCount, total);
      Interlocked.Add(ref totalMidpoint, midpt);
      
      string s = String.Format("Thread {0}:\n", Thread.CurrentThread.Name) +
                 String.Format("   Random Numbers: {0:N0}\n", total) + 
                 String.Format("   Midpoint values: {0:N0} ({1:P3})", midpt, 
                               ((double) midpt)/total);
      Console.WriteLine(s);
      cte.Signal();
   }
}
// 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
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

Das folgende Beispiel ähnelt der vorherigen, außer dass sie die Task Klasse anstelle einer Threadprozedur verwendet, um 50.000 zufällige Mittelwertzahlen zu generieren. In diesem Beispiel ersetzt ein Lambdaausdruck die GenerateNumbers Threadprozedur, und der Aufruf der Task.WaitAll Methode beseitigt die Notwendigkeit des CountdownEvent Objekts.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   const int LOWERBOUND = 0;
   const int UPPERBOUND = 1001;
   
   static Object lockObj = new Object();
   static Random rnd = new Random();
   
   static int totalCount = 0;
   static int totalMidpoint = 0;
   static int midpointCount = 50000;

   public static async Task Main()
   {
      List<Task> tasks = new List<Task>();

      // Start three tasks. 
      for (int ctr = 0; ctr <= 2; ctr++) 
         tasks.Add(Task.Run( () => { int midpoint = (UPPERBOUND - LOWERBOUND) / 2;
                                     int value = 0;
                                     int total = 0;
                                     int midpt = 0;
      
                                     do {
                                        lock (lockObj) {
                                           value = rnd.Next(LOWERBOUND, UPPERBOUND);
                                        }
                                        if (value == midpoint) { 
                                           Interlocked.Decrement(ref midpointCount);
                                           midpt++;
                                        }
                                        total++;    
                                     } while (Volatile.Read(ref midpointCount) > 0);
                                          
                                     Interlocked.Add(ref totalCount, total);
                                     Interlocked.Add(ref totalMidpoint, midpt);
                                          
                                     string s = String.Format("Task {0}:\n", Task.CurrentId) +
                                                String.Format("   Random Numbers: {0:N0}\n", total) + 
                                                String.Format("   Midpoint values: {0:N0} ({1:P3})", midpt, 
                                                              ((double) midpt)/total);
                                     Console.WriteLine(s); 
                                   } ));

      await Task.WhenAll(tasks.ToArray());

      Console.WriteLine();
      Console.WriteLine("Total midpoint values:  {0,10:N0} ({1:P3})",
                        totalMidpoint, totalMidpoint/((double)totalCount));
      Console.WriteLine("Total number of values: {0,10:N0}", 
                        totalCount);                  
   }
}
// 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
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

Hinweise

Diese Methode behandelt eine Überlaufbedingung durch Umbruch: Wenn location = Int32.MinValue, location - 1 = Int32.MaxValue. Es wird keine Ausnahme ausgelöst.

Siehe auch

Gilt für:

Decrement(Int64)

Dekrementiert den Wert der angegebenen Variablen und speichert das Ergebnis in einer atomaren Operation.

public:
 static long Decrement(long % location);
public static long Decrement (ref long location);
static member Decrement : int64 -> int64
Public Shared Function Decrement (ByRef location As Long) As Long

Parameter

location
Int64

Die Variable, deren Wert dekrementiert werden soll.

Gibt zurück

Int64

Der dekrementierte Wert.

Ausnahmen

Die Adresse von location ist ein null-Zeiger.

Die Adresse von location ist ein null-Zeiger.

Hinweise

Diese Methode behandelt eine Überlaufbedingung durch Umbruch: wenn location = Int64.MinValue, location - 1 = Int64.MaxValue. Es wird keine Ausnahme ausgelöst.

Siehe auch

Gilt für:

Decrement(UInt32)

Wichtig

Diese API ist nicht CLS-kompatibel.

Dekrementiert den Wert einer angegebenen Variablen und speichert das Ergebnis in einer atomaren Operation.

public:
 static System::UInt32 Decrement(System::UInt32 % location);
[System.CLSCompliant(false)]
public static uint Decrement (ref uint location);
[<System.CLSCompliant(false)>]
static member Decrement : uint32 -> uint32
Public Shared Function Decrement (ByRef location As UInteger) As UInteger

Parameter

location
UInt32

Die Variable, deren Wert dekrementiert werden soll.

Gibt zurück

UInt32

Der dekrementierte Wert.

Attribute

Ausnahmen

Die Adresse von location ist ein null-Zeiger.

Gilt für:

Decrement(UInt64)

Wichtig

Diese API ist nicht CLS-kompatibel.

Dekrementiert den Wert einer angegebenen Variablen und speichert das Ergebnis in einer atomaren Operation.

public:
 static System::UInt64 Decrement(System::UInt64 % location);
[System.CLSCompliant(false)]
public static ulong Decrement (ref ulong location);
[<System.CLSCompliant(false)>]
static member Decrement : uint64 -> uint64
Public Shared Function Decrement (ByRef location As ULong) As ULong

Parameter

location
UInt64

Die Variable, deren Wert dekrementiert werden soll.

Gibt zurück

UInt64

Der dekrementierte Wert.

Attribute

Ausnahmen

Die Adresse von location ist ein null-Zeiger.

Gilt für: