Interlocked.Increment Método

Definição

Incrementa uma variável especificada e armazena o resultado, como uma operação atômica.

Sobrecargas

Increment(UInt64)

Incrementa uma variável especificada e armazena o resultado, como uma operação atômica.

Increment(UInt32)

Incrementa uma variável especificada e armazena o resultado, como uma operação atômica.

Increment(Int32)

Incrementa uma variável especificada e armazena o resultado, como uma operação atômica.

Increment(Int64)

Incrementa uma variável especificada e armazena o resultado, como uma operação atômica.

Increment(UInt64)

Origem:
Interlocked.cs
Origem:
Interlocked.cs
Origem:
Interlocked.cs

Importante

Esta API não está em conformidade com CLS.

Incrementa uma variável especificada e armazena o resultado, como uma operação atômica.

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

Parâmetros

location
UInt64

A variável cujo valor deve ser incrementado.

Retornos

O valor da variável imediatamente após a conclusão da operação de incremento.

Atributos

Exceções

O endereço de location é um ponteiro null.

Aplica-se a

.NET 9 e outras versões
Produto Versões
.NET 5, 6, 7, 8, 9

Increment(UInt32)

Origem:
Interlocked.cs
Origem:
Interlocked.cs
Origem:
Interlocked.cs

Importante

Esta API não está em conformidade com CLS.

Incrementa uma variável especificada e armazena o resultado, como uma operação atômica.

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

Parâmetros

location
UInt32

A variável cujo valor deve ser incrementado.

Retornos

O valor da variável imediatamente após a conclusão da operação de incremento.

Atributos

Exceções

O endereço de location é um ponteiro null.

Aplica-se a

.NET 9 e outras versões
Produto Versões
.NET 5, 6, 7, 8, 9

Increment(Int32)

Origem:
Interlocked.CoreCLR.cs
Origem:
Interlocked.CoreCLR.cs
Origem:
Interlocked.CoreCLR.cs

Incrementa uma variável especificada e armazena o resultado, como uma operação atômica.

public static int Increment (ref int location);

Parâmetros

location
Int32

A variável cujo valor deve ser incrementado.

Retornos

O valor da variável imediatamente após a conclusão da operação de incremento.

Exceções

O endereço de location é um ponteiro null.

Exemplos

O exemplo a seguir determina quantos números aleatórios que variam de 0 a 1.000 são necessários para gerar 1.000 números aleatórios com um valor de ponto médio. Para acompanhar o número de valores de ponto médio, uma variável, midpointCount, é definida como 0 e incrementada sempre que o gerador de número aleatório retorna um valor de ponto médio até atingir 10.000. Como três threads geram os números aleatórios, o Increment(Int32) método é chamado para garantir que vários threads não sejam atualizados midpointCount simultaneamente. Observe que um bloqueio também é usado para proteger o gerador de números aleatórios e que um CountdownEvent objeto é usado para garantir que o método não conclua a Main execução antes dos três threads.

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

O exemplo a seguir é semelhante ao anterior, exceto que ele usa a Task classe em vez de um procedimento de thread para gerar 50.000 inteiros de ponto médio aleatórios. Neste exemplo, uma expressão lambda substitui o GenerateNumbers procedimento de thread e a chamada para o Task.WaitAll método elimina a necessidade do CountdownEvent objeto.

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

Comentários

Esse método manipula uma condição de estouro encapsulando: se location = Int32.MaxValue, location + 1 = Int32.MinValue. Nenhuma exceção é gerada.

Confira também

Aplica-se a

.NET 9 e outras versões
Produto Versões
.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
.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)

Origem:
Interlocked.CoreCLR.cs
Origem:
Interlocked.CoreCLR.cs
Origem:
Interlocked.CoreCLR.cs

Incrementa uma variável especificada e armazena o resultado, como uma operação atômica.

public static long Increment (ref long location);

Parâmetros

location
Int64

A variável cujo valor deve ser incrementado.

Retornos

O valor da variável imediatamente após a conclusão da operação de incremento.

Exceções

O endereço de location é um ponteiro null.

Comentários

Esse método manipula uma condição de estouro encapsulando: se location = Int64.MaxValue, location + 1 = Int64.MinValue. Nenhuma exceção é gerada.

Confira também

Aplica-se a

.NET 9 e outras versões
Produto Versões
.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
.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