Interlocked.Increment 方法

定义

以原子操作的形式递增指定变量的值并存储结果。

重载

Increment(UInt64)

以原子操作的形式递增指定变量的值并存储结果。

Increment(UInt32)

以原子操作的形式递增指定变量的值并存储结果。

Increment(Int32)

以原子操作的形式递增指定变量的值并存储结果。

Increment(Int64)

以原子操作的形式递增指定变量的值并存储结果。

Increment(UInt64)

Source:
Interlocked.cs
Source:
Interlocked.cs
Source:
Interlocked.cs

重要

此 API 不符合 CLS。

以原子操作的形式递增指定变量的值并存储结果。

[System.CLSCompliant(false)]
public static ulong Increment(ref ulong location);

参数

location
UInt64

其值要递增的变量。

返回

增量操作完成后紧接变量的值。

属性

例外

location 的地址是一个 null 指针。

适用于

.NET 10 和其他版本
产品 版本
.NET 5, 6, 7, 8, 9, 10

Increment(UInt32)

Source:
Interlocked.cs
Source:
Interlocked.cs
Source:
Interlocked.cs

重要

此 API 不符合 CLS。

以原子操作的形式递增指定变量的值并存储结果。

[System.CLSCompliant(false)]
public static uint Increment(ref uint location);

参数

location
UInt32

其值要递增的变量。

返回

增量操作完成后紧接变量的值。

属性

例外

location 的地址是一个 null 指针。

适用于

.NET 10 和其他版本
产品 版本
.NET 5, 6, 7, 8, 9, 10

Increment(Int32)

Source:
Interlocked.CoreCLR.cs
Source:
Interlocked.CoreCLR.cs
Source:
Interlocked.CoreCLR.cs

以原子操作的形式递增指定变量的值并存储结果。

public static int Increment(ref int location);

参数

location
Int32

其值要递增的变量。

返回

增量操作完成后紧接变量的值。

例外

location 的地址是一个 null 指针。

示例

以下示例确定需要多少个介于 0 到 1,000 的随机数才能生成具有中点值的 1,000 个随机数。 为了跟踪中点值的数量, midpointCount变量 设置为等于 0,并在随机数生成器每次返回中点值时递增,直到它达到 10,000。 由于三个线程生成随机数, Increment(Int32) 因此调用 方法以确保多个线程不会同时更新 midpointCount 。 请注意,锁还用于保护随机数生成器,并使用 对象来确保Main方法不会在三个CountdownEvent线程之前完成执行。

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 = 0;

   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.Increment(ref midpointCount);
            midpt++;
         }
         total++;    
      } while (Volatile.Read(ref midpointCount) < 10000);
      
      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: 2,776,674
//          Midpoint values: 2,773 (0.100 %)
//       Thread Thread1:
//          Random Numbers: 4,876,100
//          Midpoint values: 4,873 (0.100 %)
//       Thread Thread0:
//          Random Numbers: 2,312,310
//          Midpoint values: 2,354 (0.102 %)
//       
//       Total midpoint values:      10,000 (0.100 %)
//       Total number of values:  9,965,084

下面的示例与上一个示例类似,只不过它使用 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 = 0;

   public static void 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.Increment(ref midpointCount);
                                           midpt++;
                                        }
                                        total++;    
                                     } while (Volatile.Read(ref midpointCount) < 50000);
                                    
                                     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); } ));
      
      Task.WaitAll(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 3:
//          Random Numbers: 10,855,250
//          Midpoint values: 10,823 (0.100 %)
//       Task 1:
//          Random Numbers: 15,243,703
//          Midpoint values: 15,110 (0.099 %)
//       Task 2:
//          Random Numbers: 24,107,425
//          Midpoint values: 24,067 (0.100 %)
//       
//       Total midpoint values:      50,000 (0.100 %)
//       Total number of values: 50,206,378

注解

此方法通过包装处理溢出条件:如果 location = Int32.MaxValuelocation + 1 = 。 Int32.MinValue 不会引发异常。

另请参阅

适用于

.NET 10 和其他版本
产品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.6, 2.0, 2.1
UWP 10.0

Increment(Int64)

Source:
Interlocked.CoreCLR.cs
Source:
Interlocked.CoreCLR.cs
Source:
Interlocked.CoreCLR.cs

以原子操作的形式递增指定变量的值并存储结果。

public static long Increment(ref long location);

参数

location
Int64

其值要递增的变量。

返回

增量操作完成后紧接变量的值。

例外

location 的地址是一个 null 指针。

注解

此方法通过包装处理溢出条件:如果 location = Int64.MaxValuelocation + 1 = 。 Int64.MinValue 不会引发异常。

另请参阅

适用于

.NET 10 和其他版本
产品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.6, 2.0, 2.1
UWP 10.0