Interlocked.Decrement 方法

定義

遞減指定變數並儲存結果,作為原子操作。

多載

名稱 Description
Decrement(Int64)

遞減指定的變數並將結果儲存為原子操作。

Decrement(Int32)

遞減指定變數並儲存結果,作為原子操作。

Decrement(UInt32)

遞減指定變數並儲存結果,作為原子操作。

Decrement(UInt64)

遞減指定變數並儲存結果,作為原子操作。

Decrement(Int64)

來源:
Interlocked.CoreCLR.cs
來源:
Interlocked.CoreCLR.cs
來源:
Interlocked.CoreCLR.cs
來源:
Interlocked.CoreCLR.cs
來源:
Interlocked.CoreCLR.cs

遞減指定的變數並將結果儲存為原子操作。

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

參數

location
Int64

該變數的值要遞減。

傳回

遞減操作結束後,變數的值會立即出現。

例外狀況

location 位址是一個 null 指標。

location 位址是一個 null 指標。

備註

此方法處理溢位條件時,會將 包裹為:如果 location = Int64.MinValue, - location 1 = Int64.MaxValue。 沒例外拋出。

另請參閱

適用於

Decrement(Int32)

來源:
Interlocked.CoreCLR.cs
來源:
Interlocked.CoreCLR.cs
來源:
Interlocked.CoreCLR.cs
來源:
Interlocked.CoreCLR.cs
來源:
Interlocked.CoreCLR.cs

遞減指定變數並儲存結果,作為原子操作。

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

參數

location
Int32

該變數的值要遞減。

傳回

遞減操作結束後,變數的值會立即出現。

例外狀況

location 位址是一個 null 指標。

location 位址是一個 null 指標。

範例

以下範例決定產生1,000個中點數的隨機數,需要多少個介於0到1,000的隨機數。 為了記錄中點數的數量,會設定一個變數 midpointCount,等於 1,000,並在隨機數產生器回傳中點值時,變數會遞減。 由於三個執行緒會產生隨機數,因此呼叫此 Decrement(Int32) 方法以確保多個執行緒不會同時更新 midpointCount 。 請注意,鎖同時用於保護隨機數產生器,並 CountdownEvent 使用物件確保 Main 方法不會在三個執行緒完成前完成執行。

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

以下範例與前一個相似,但使用 Task 類別而非執行緒程序,產生 50,000 個隨機中點整數。 在此範例中,lambda 運算式取代 GenerateNumbers 了執行緒程序,而呼叫該 Task.WaitAll 方法則消除了對物件 CountdownEvent 的需求。

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

備註

此方法處理溢位條件時,會將:如果 location = Int32.MinValue, - location 1 = 。 Int32.MaxValue 沒例外拋出。

另請參閱

適用於

Decrement(UInt32)

來源:
Interlocked.cs
來源:
Interlocked.cs
來源:
Interlocked.cs
來源:
Interlocked.cs
來源:
Interlocked.cs

重要

此 API 不符合 CLS 規範。

遞減指定變數並儲存結果,作為原子操作。

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

參數

location
UInt32

該變數的值要遞減。

傳回

遞減操作結束後,變數的值會立即出現。

屬性

例外狀況

location 位址是一個 null 指標。

適用於

Decrement(UInt64)

來源:
Interlocked.cs
來源:
Interlocked.cs
來源:
Interlocked.cs
來源:
Interlocked.cs
來源:
Interlocked.cs

重要

此 API 不符合 CLS 規範。

遞減指定變數並儲存結果,作為原子操作。

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

參數

location
UInt64

該變數的值要遞減。

傳回

遞減操作結束後,變數的值會立即出現。

屬性

例外狀況

location 位址是一個 null 指標。

適用於