Interlocked.CompareExchange Método

Definição

Compara dois valores para verificar se são iguais e, em caso de igualdade, substitui o primeiro valor.

Sobrecargas

CompareExchange(UIntPtr, UIntPtr, UIntPtr)

Compara dois ponteiros ou identificadores específicos da plataforma quanto à igualdade e, se eles são iguais, substitui o primeiro.

CompareExchange(UInt64, UInt64, UInt64)

Compara dois inteiros sem sinal de 64 bits para verificar se são iguais e, em caso de igualdade, substitui o primeiro valor.

CompareExchange(UInt32, UInt32, UInt32)

Compara dois inteiros sem sinal de 32 bits para verificar se são iguais e, em caso de igualdade, substitui o primeiro valor.

CompareExchange(UInt16, UInt16, UInt16)
CompareExchange(Single, Single, Single)

Compara se dois números de ponto flutuante de precisão simples são iguais e, se eles são, substitui o primeiro valor.

CompareExchange(Object, Object, Object)

Compara dois objetos quanto à igualdade de referência e, se eles forem iguais, substitui o primeiro objeto.

CompareExchange(SByte, SByte, SByte)
CompareExchange(Int64, Int64, Int64)

Compara dois inteiros com sinal de 64 bits para verificar se são iguais e, em caso de igualdade, substitui o primeiro valor.

CompareExchange(Int32, Int32, Int32)

Compara dois inteiros com sinal de 32 bits para verificar se são iguais e, em caso de igualdade, substitui o primeiro valor.

CompareExchange(Int16, Int16, Int16)
CompareExchange(Double, Double, Double)

Compara se dois pontos flutuantes de precisão dupla são iguais e, se eles forem, substitui o primeiro valor.

CompareExchange(Byte, Byte, Byte)
CompareExchange(IntPtr, IntPtr, IntPtr)

Compara dois ponteiros ou identificadores específicos da plataforma quanto à igualdade e, se eles são iguais, substitui o primeiro.

CompareExchange<T>(T, T, T)

Compara duas instâncias do tipo de referência T especificado em relação à igualdade e, se elas forem iguais, substitui a primeira.

CompareExchange(UIntPtr, UIntPtr, UIntPtr)

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

Importante

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

Compara dois ponteiros ou identificadores específicos da plataforma quanto à igualdade e, se eles são iguais, substitui o primeiro.

public:
 static UIntPtr CompareExchange(UIntPtr % location1, UIntPtr value, UIntPtr comparand);
[System.CLSCompliant(false)]
public static UIntPtr CompareExchange (ref UIntPtr location1, UIntPtr value, UIntPtr comparand);
[<System.CLSCompliant(false)>]
static member CompareExchange : unativeint * unativeint * unativeint -> unativeint
Public Shared Function CompareExchange (ByRef location1 As UIntPtr, value As UIntPtr, comparand As UIntPtr) As UIntPtr

Parâmetros

location1
UIntPtr

unativeint

O UIntPtr de destino, cujo valor é comparado com o valor de comparand e possivelmente substituído por value.

value
UIntPtr

unativeint

O UIntPtr que substitui o valor de destino quando a comparação resulta em igualdade.

comparand
UIntPtr

unativeint

O UIntPtr comparado ao valor em location1.

Retornos

UIntPtr

unativeint

O valor original em location1.

Atributos

Exceções

O endereço de location1 é um ponteiro null.

Aplica-se a

CompareExchange(UInt64, UInt64, UInt64)

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

Importante

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

Compara dois inteiros sem sinal de 64 bits para verificar se são iguais e, em caso de igualdade, substitui o primeiro valor.

public:
 static System::UInt64 CompareExchange(System::UInt64 % location1, System::UInt64 value, System::UInt64 comparand);
[System.CLSCompliant(false)]
public static ulong CompareExchange (ref ulong location1, ulong value, ulong comparand);
[<System.CLSCompliant(false)>]
static member CompareExchange : uint64 * uint64 * uint64 -> uint64
Public Shared Function CompareExchange (ByRef location1 As ULong, value As ULong, comparand As ULong) As ULong

Parâmetros

location1
UInt64

O destino, cujo valor é comparado com comparand e possivelmente substituído.

value
UInt64

O valor que substitui o valor de destino quando a comparação resulta em igualdade.

comparand
UInt64

O valor comparado ao valor em location1.

Retornos

O valor original em location1.

Atributos

Exceções

O endereço de location1 é um ponteiro null.

Aplica-se a

CompareExchange(UInt32, UInt32, UInt32)

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

Importante

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

Compara dois inteiros sem sinal de 32 bits para verificar se são iguais e, em caso de igualdade, substitui o primeiro valor.

public:
 static System::UInt32 CompareExchange(System::UInt32 % location1, System::UInt32 value, System::UInt32 comparand);
[System.CLSCompliant(false)]
public static uint CompareExchange (ref uint location1, uint value, uint comparand);
[<System.CLSCompliant(false)>]
static member CompareExchange : uint32 * uint32 * uint32 -> uint32
Public Shared Function CompareExchange (ByRef location1 As UInteger, value As UInteger, comparand As UInteger) As UInteger

Parâmetros

location1
UInt32

O destino, cujo valor é comparado com comparand e possivelmente substituído.

value
UInt32

O valor que substitui o valor de destino quando a comparação resulta em igualdade.

comparand
UInt32

O valor comparado ao valor em location1.

Retornos

O valor original em location1.

Atributos

Exceções

O endereço de location1 é um ponteiro null.

Aplica-se a

CompareExchange(UInt16, UInt16, UInt16)

Importante

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

public:
 static System::UInt16 CompareExchange(System::UInt16 % location1, System::UInt16 value, System::UInt16 comparand);
[System.CLSCompliant(false)]
public static ushort CompareExchange (ref ushort location1, ushort value, ushort comparand);
[<System.CLSCompliant(false)>]
static member CompareExchange : uint16 * uint16 * uint16 -> uint16
Public Shared Function CompareExchange (ByRef location1 As UShort, value As UShort, comparand As UShort) As UShort

Parâmetros

location1
UInt16
value
UInt16
comparand
UInt16

Retornos

Atributos

Aplica-se a

CompareExchange(Single, Single, Single)

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

Compara se dois números de ponto flutuante de precisão simples são iguais e, se eles são, substitui o primeiro valor.

public:
 static float CompareExchange(float % location1, float value, float comparand);
public static float CompareExchange (ref float location1, float value, float comparand);
static member CompareExchange : single * single * single -> single
Public Shared Function CompareExchange (ByRef location1 As Single, value As Single, comparand As Single) As Single

Parâmetros

location1
Single

O destino, cujo valor é comparado com comparand e possivelmente substituído.

value
Single

O valor que substitui o valor de destino quando a comparação resulta em igualdade.

comparand
Single

O valor comparado ao valor em location1.

Retornos

O valor original em location1.

Exceções

O endereço de location1 é um ponteiro nulo.

Exemplos

O exemplo de código a seguir demonstra um método thread-safe que acumula um total de Single valores em execução. Dois threads adicionam uma série de Single valores usando o método thread-safe e a adição comum e quando os threads concluem os totais são comparados. Em um computador com processador duplo, há uma diferença significativa nos totais.

No método thread-safe, o valor inicial do total em execução é salvo e, em seguida, o CompareExchange método é usado para trocar o total calculado recentemente com o total antigo. Se o valor retornado não for igual ao valor salvo do total em execução, outro thread atualizou o total enquanto isso. Nesse caso, a tentativa de atualizar o total em execução deve ser repetida.

// This example demonstrates a thread-safe method that adds to a
// running total.  
using System;
using System.Threading;

public class ThreadSafe
{
    // Field totalValue contains a running total that can be updated
    // by multiple threads. It must be protected from unsynchronized 
    // access.
    private float totalValue = 0.0F;

    // The Total property returns the running total.
    public float Total { get { return totalValue; }}

    // AddToTotal safely adds a value to the running total.
    public float AddToTotal(float addend)
    {
        float initialValue, computedValue;
        do
        {
            // Save the current running total in a local variable.
            initialValue = totalValue;

            // Add the new value to the running total.
            computedValue = initialValue + addend;

            // CompareExchange compares totalValue to initialValue. If
            // they are not equal, then another thread has updated the
            // running total since this loop started. CompareExchange
            // does not update totalValue. CompareExchange returns the
            // contents of totalValue, which do not equal initialValue,
            // so the loop executes again.
        }
        while (initialValue != Interlocked.CompareExchange(ref totalValue, 
            computedValue, initialValue));
        // If no other thread updated the running total, then 
        // totalValue and initialValue are equal when CompareExchange
        // compares them, and computedValue is stored in totalValue.
        // CompareExchange returns the value that was in totalValue
        // before the update, which is equal to initialValue, so the 
        // loop ends.

        // The function returns computedValue, not totalValue, because
        // totalValue could be changed by another thread between
        // the time the loop ends and the function returns.
        return computedValue;
    }
}

public class Test
{
    // Create an instance of the ThreadSafe class to test.
    private static ThreadSafe ts = new ThreadSafe();
    private static float control;

    private static Random r = new Random();
    private static ManualResetEvent mre = new ManualResetEvent(false);

    public static void Main()
    {
        // Create two threads, name them, and start them. The
        // thread will block on mre.
        Thread t1 = new Thread(TestThread);
        t1.Name = "Thread 1";
        t1.Start();
        Thread t2 = new Thread(TestThread);
        t2.Name = "Thread 2";
        t2.Start();

        // Now let the threads begin adding random numbers to 
        // the total.
        mre.Set();
        
        // Wait until all the threads are done.
        t1.Join();
        t2.Join();

        Console.WriteLine("Thread safe: {0}  Ordinary float: {1}", 
            ts.Total, control);
    }

    private static void TestThread()
    {
        // Wait until the signal.
        mre.WaitOne();

        for(int i = 1; i <= 1000000; i++)
        {
            // Add to the running total in the ThreadSafe instance, and
            // to an ordinary float.
            //
            float testValue = (float) r.NextDouble();
            control += testValue;
            ts.AddToTotal(testValue);
        }
    }
}

/* On a dual-processor computer, this code example produces output 
   similar to the following:

Thread safe: 17039.57  Ordinary float: 15706.44
 */
' This example demonstrates a thread-safe method that adds to a
' running total.  
Imports System.Threading

Public Class ThreadSafe
    ' Field totalValue contains a running total that can be updated
    ' by multiple threads. It must be protected from unsynchronized 
    ' access.
    Private totalValue As Single = 0.0

    ' The Total property returns the running total.
    Public ReadOnly Property Total As Single
        Get
            Return totalValue
        End Get
    End Property

    ' AddToTotal safely adds a value to the running total.
    Public Function AddToTotal(ByVal addend As Single) As Single
        Dim initialValue, computedValue As Single
        Do
            ' Save the current running total in a local variable.
            initialValue = totalValue

            ' Add the new value to the running total.
            computedValue = initialValue + addend

            ' CompareExchange compares totalValue to initialValue. If
            ' they are not equal, then another thread has updated the
            ' running total since this loop started. CompareExchange
            ' does not update totalValue. CompareExchange returns the
            ' contents of totalValue, which do not equal initialValue,
            ' so the loop executes again.
        Loop While initialValue <> Interlocked.CompareExchange( _
            totalValue, computedValue, initialValue)
        ' If no other thread updated the running total, then 
        ' totalValue and initialValue are equal when CompareExchange
        ' compares them, and computedValue is stored in totalValue.
        ' CompareExchange returns the value that was in totalValue
        ' before the update, which is equal to initialValue, so the 
        ' loop ends.

        ' The function returns computedValue, not totalValue, because
        ' totalValue could be changed by another thread between
        ' the time the loop ends and the function returns.
        Return computedValue
    End Function
End Class

Public Class Test
    ' Create an instance of the ThreadSafe class to test.
    Private Shared ts As New ThreadSafe()
    Private Shared control As Single

    Private Shared r As New Random()
    Private Shared mre As New ManualResetEvent(false)

    <MTAThread> _
    Public Shared Sub Main()
        ' Create two threads, name them, and start them. The
        ' threads will block on mre.
        Dim t1 As New Thread(AddressOf TestThread)
        t1.Name = "Thread 1"
        t1.Start()
        Dim t2 As New Thread(AddressOf TestThread)
        t2.Name = "Thread 2"
        t2.Start()

        ' Now let the threads begin adding random numbers to 
        ' the total.
        mre.Set()
        
        ' Wait until all the threads are done.
        t1.Join()
        t2.Join()

        Console.WriteLine("Thread safe: {0}  Ordinary Single: {1}", ts.Total, control)
    End Sub

    Private Shared Sub TestThread()
        ' Wait until the signal.
        mre.WaitOne()

        For i As Integer = 1 to 1000000
            ' Add to the running total in the ThreadSafe instance, and
            ' to an ordinary Single.
            '
            Dim testValue As Single = r.NextDouble()
            control += testValue
            ts.AddToTotal(testValue)
        Next
    End Sub
End Class

' On a dual-processor computer, this code example produces output 
' similar to the following:
'
'Thread safe: 17039.57  Ordinary Single: 15706.44

Comentários

Se comparand e o valor em location1 forem iguais, será value armazenado em location1. Caso contrário, nenhuma operação será executada. As operações de comparação e troca são executadas como uma operação atômica. O valor retornado de CompareExchange é o valor original em location1, independentemente de a troca ocorrer ou não.

Confira também

Aplica-se a

CompareExchange(Object, Object, Object)

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

Compara dois objetos quanto à igualdade de referência e, se eles forem iguais, substitui o primeiro objeto.

public:
 static System::Object ^ CompareExchange(System::Object ^ % location1, System::Object ^ value, System::Object ^ comparand);
public static object CompareExchange (ref object location1, object value, object comparand);
public static object? CompareExchange (ref object? location1, object? value, object? comparand);
static member CompareExchange : obj * obj * obj -> obj
Public Shared Function CompareExchange (ByRef location1 As Object, value As Object, comparand As Object) As Object

Parâmetros

location1
Object

O objeto de destino que é comparado pela referência com comparand e possivelmente substituído.

value
Object

O objeto que substitui o objeto de destino quando a comparação de referência resulta em igualdade.

comparand
Object

O objeto que é comparado pela referência ao objeto em location1.

Retornos

O valor original em location1.

Exceções

O endereço de location1 é um ponteiro null.

Comentários

Importante

Começando com o .NET Framework 2.0, a sobrecarga do método CompareExchange<T>(T, T, T) fornece uma alternativa fortemente tipada para tipos de referência. Recomendamos que você a chame em vez dessa sobrecarga.

Se comparand e o objeto em location1 forem iguais por referência, será value armazenado em location1. Caso contrário, nenhuma operação será executada. As operações de comparação e troca são executadas como uma operação atômica. O valor retornado de CompareExchange é o valor original em location1, independentemente de a troca ocorrer ou não.

Observação

Os objetos são comparados quanto à igualdade de referência em vez da igualdade de valor. Como resultado, duas instâncias em caixa do mesmo tipo de valor (por exemplo, o inteiro 3) sempre parecem ser diferentes e nenhuma operação é executada. Não use essa sobrecarga com tipos de valor.

Confira também

Aplica-se a

CompareExchange(SByte, SByte, SByte)

Importante

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

public:
 static System::SByte CompareExchange(System::SByte % location1, System::SByte value, System::SByte comparand);
[System.CLSCompliant(false)]
public static sbyte CompareExchange (ref sbyte location1, sbyte value, sbyte comparand);
[<System.CLSCompliant(false)>]
static member CompareExchange : sbyte * sbyte * sbyte -> sbyte
Public Shared Function CompareExchange (ByRef location1 As SByte, value As SByte, comparand As SByte) As SByte

Parâmetros

location1
SByte
value
SByte
comparand
SByte

Retornos

Atributos

Aplica-se a

CompareExchange(Int64, Int64, Int64)

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

Compara dois inteiros com sinal de 64 bits para verificar se são iguais e, em caso de igualdade, substitui o primeiro valor.

public:
 static long CompareExchange(long % location1, long value, long comparand);
public static long CompareExchange (ref long location1, long value, long comparand);
static member CompareExchange : int64 * int64 * int64 -> int64
Public Shared Function CompareExchange (ByRef location1 As Long, value As Long, comparand As Long) As Long

Parâmetros

location1
Int64

O destino, cujo valor é comparado com comparand e possivelmente substituído.

value
Int64

O valor que substitui o valor de destino quando a comparação resulta em igualdade.

comparand
Int64

O valor comparado ao valor em location1.

Retornos

O valor original em location1.

Exceções

O endereço de location1 é um ponteiro nulo.

Comentários

Se comparand e o valor em location1 forem iguais, será value armazenado em location1. Caso contrário, nenhuma operação será executada. As operações de comparação e troca são executadas como uma operação atômica. O valor retornado de CompareExchange é o valor original em location1, independentemente de a troca ocorrer ou não.

Confira também

Aplica-se a

CompareExchange(Int32, Int32, Int32)

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

Compara dois inteiros com sinal de 32 bits para verificar se são iguais e, em caso de igualdade, substitui o primeiro valor.

public:
 static int CompareExchange(int % location1, int value, int comparand);
public static int CompareExchange (ref int location1, int value, int comparand);
static member CompareExchange : int * int * int -> int
Public Shared Function CompareExchange (ByRef location1 As Integer, value As Integer, comparand As Integer) As Integer

Parâmetros

location1
Int32

O destino, cujo valor é comparado com comparand e possivelmente substituído.

value
Int32

O valor que substitui o valor de destino quando a comparação resulta em igualdade.

comparand
Int32

O valor comparado ao valor em location1.

Retornos

O valor original em location1.

Exceções

O endereço de location1 é um ponteiro nulo.

Exemplos

O exemplo de código a seguir demonstra um método thread-safe que acumula um total em execução. O valor inicial do total em execução é salvo e, em seguida, o CompareExchange método é usado para trocar o total calculado recentemente com o total antigo. Se o valor retornado não for igual ao valor salvo do total em execução, outro thread atualizou o total enquanto isso. Nesse caso, a tentativa de atualizar o total em execução deve ser repetida.

Observação

O Add método, introduzido na versão 2.0 do .NET Framework, fornece uma maneira mais conveniente de acumular totais de execução thread-safe para inteiros.

// This example demonstrates a thread-safe method that adds to a
// running total.  It cannot be run directly.  You can compile it
// as a library, or add the class to a project.
#using <system.dll>

using namespace System::Threading;
public ref class ThreadSafe
{
private:

   // totalValue contains a running total that can be updated
   // by multiple threads. It must be protected from unsynchronized 
   // access.
   int totalValue;

public:

   property int Total 
   {

      // The Total property returns the running total.
      int get()
      {
         return totalValue;
      }

   }

   // AddToTotal safely adds a value to the running total.
   int AddToTotal( int addend )
   {
      int initialValue;
      int computedValue;
      do
      {
         
         // Save the current running total in a local variable.
         initialValue = totalValue;
         
         // Add the new value to the running total.
         computedValue = initialValue + addend;
         
         // CompareExchange compares totalValue to initialValue. If
         // they are not equal, then another thread has updated the
         // running total since this loop started. CompareExchange
         // does not update totalValue. CompareExchange returns the
         // contents of totalValue, which do not equal initialValue,
         // so the loop executes again.
      }
      while ( initialValue != Interlocked::CompareExchange( totalValue, computedValue, initialValue ) );

      
      // If no other thread updated the running total, then 
      // totalValue and initialValue are equal when CompareExchange
      // compares them, and computedValue is stored in totalValue.
      // CompareExchange returns the value that was in totalValue
      // before the update, which is equal to initialValue, so the 
      // loop ends.
      // The function returns computedValue, not totalValue, because
      // totalValue could be changed by another thread between
      // the time the loop ends and the function returns.
      return computedValue;
   }

};
// This example demonstrates a thread-safe method that adds to a
// running total.  It cannot be run directly.  You can compile it
// as a library, or add the class to a project.
using System.Threading;

public class ThreadSafe {
    // totalValue contains a running total that can be updated
    // by multiple threads. It must be protected from unsynchronized 
    // access.
    private int totalValue = 0;

    // The Total property returns the running total.
    public int Total {
        get { return totalValue; }
    }

    // AddToTotal safely adds a value to the running total.
    public int AddToTotal(int addend) {
        int initialValue, computedValue;
        do {
            // Save the current running total in a local variable.
            initialValue = totalValue;

            // Add the new value to the running total.
            computedValue = initialValue + addend;

            // CompareExchange compares totalValue to initialValue. If
            // they are not equal, then another thread has updated the
            // running total since this loop started. CompareExchange
            // does not update totalValue. CompareExchange returns the
            // contents of totalValue, which do not equal initialValue,
            // so the loop executes again.
        } while (initialValue != Interlocked.CompareExchange(
            ref totalValue, computedValue, initialValue));
        // If no other thread updated the running total, then 
        // totalValue and initialValue are equal when CompareExchange
        // compares them, and computedValue is stored in totalValue.
        // CompareExchange returns the value that was in totalValue
        // before the update, which is equal to initialValue, so the 
        // loop ends.

        // The function returns computedValue, not totalValue, because
        // totalValue could be changed by another thread between
        // the time the loop ends and the function returns.
        return computedValue;
    }
}
' This example demonstrates a thread-safe method that adds to a
' running total.  It cannot be run directly.  You can compile it
' as a library, or add the class to a project.
Imports System.Threading

Public Class ThreadSafe
    ' Field totalValue contains a running total that can be updated
    ' by multiple threads. It must be protected from unsynchronized 
    ' access.
    Private totalValue As Integer = 0

    ' The Total property returns the running total.
    Public ReadOnly Property Total As Integer
        Get
            Return totalValue
        End Get
    End Property

    ' AddToTotal safely adds a value to the running total.
    Public Function AddToTotal(ByVal addend As Integer) As Integer
        Dim initialValue, computedValue As Integer
        Do
            ' Save the current running total in a local variable.
            initialValue = totalValue

            ' Add the new value to the running total.
            computedValue = initialValue + addend

            ' CompareExchange compares totalValue to initialValue. If
            ' they are not equal, then another thread has updated the
            ' running total since this loop started. CompareExchange
            ' does not update totalValue. CompareExchange returns the
            ' contents of totalValue, which do not equal initialValue,
            ' so the loop executes again.
        Loop While initialValue <> Interlocked.CompareExchange( _
            totalValue, computedValue, initialValue)
        ' If no other thread updated the running total, then 
        ' totalValue and initialValue are equal when CompareExchange
        ' compares them, and computedValue is stored in totalValue.
        ' CompareExchange returns the value that was in totalValue
        ' before the update, which is equal to initialValue, so the 
        ' loop ends.

        ' The function returns computedValue, not totalValue, because
        ' totalValue could be changed by another thread between
        ' the time the loop ends and the function returns.
        Return computedValue
    End Function
End Class

Comentários

Se comparand e o valor em location1 forem iguais, será value armazenado em location1. Caso contrário, nenhuma operação será executada. As operações de comparação e troca são executadas como uma operação atômica. O valor retornado de CompareExchange é o valor original em location1, independentemente de a troca ocorrer ou não.

Confira também

Aplica-se a

CompareExchange(Int16, Int16, Int16)

public:
 static short CompareExchange(short % location1, short value, short comparand);
public static short CompareExchange (ref short location1, short value, short comparand);
static member CompareExchange : int16 * int16 * int16 -> int16
Public Shared Function CompareExchange (ByRef location1 As Short, value As Short, comparand As Short) As Short

Parâmetros

location1
Int16
value
Int16
comparand
Int16

Retornos

Aplica-se a

CompareExchange(Double, Double, Double)

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

Compara se dois pontos flutuantes de precisão dupla são iguais e, se eles forem, substitui o primeiro valor.

public:
 static double CompareExchange(double % location1, double value, double comparand);
public static double CompareExchange (ref double location1, double value, double comparand);
static member CompareExchange : double * double * double -> double
Public Shared Function CompareExchange (ByRef location1 As Double, value As Double, comparand As Double) As Double

Parâmetros

location1
Double

O destino, cujo valor é comparado com comparand e possivelmente substituído.

value
Double

O valor que substitui o valor de destino quando a comparação resulta em igualdade.

comparand
Double

O valor comparado ao valor em location1.

Retornos

O valor original em location1.

Exceções

O endereço de location1 é um ponteiro nulo.

Exemplos

O exemplo de código a seguir demonstra um método thread-safe que acumula um total de Double valores em execução. Dois threads adicionam uma série de Double valores usando o método thread-safe e a adição comum e quando os threads completam os totais são comparados. Em um computador com processador duplo, há uma diferença significativa nos totais.

No método thread-safe, o valor inicial do total em execução é salvo e, em seguida, o CompareExchange método é usado para trocar o total computado recentemente com o total antigo. Se o valor retornado não for igual ao valor salvo do total em execução, outro thread atualizará o total enquanto isso. Nesse caso, a tentativa de atualizar o total em execução deve ser repetida.

// This example demonstrates a thread-safe method that adds to a
// running total.  
using System;
using System.Threading;

public class ThreadSafe
{
    // Field totalValue contains a running total that can be updated
    // by multiple threads. It must be protected from unsynchronized 
    // access.
    private double totalValue = 0.0;

    // The Total property returns the running total.
    public double Total { get { return totalValue; }}

    // AddToTotal safely adds a value to the running total.
    public double AddToTotal(double addend)
    {
        double initialValue, computedValue;
        do
        {
            // Save the current running total in a local variable.
            initialValue = totalValue;

            // Add the new value to the running total.
            computedValue = initialValue + addend;

            // CompareExchange compares totalValue to initialValue. If
            // they are not equal, then another thread has updated the
            // running total since this loop started. CompareExchange
            // does not update totalValue. CompareExchange returns the
            // contents of totalValue, which do not equal initialValue,
            // so the loop executes again.
        }
        while (initialValue != Interlocked.CompareExchange(ref totalValue, 
            computedValue, initialValue));
        // If no other thread updated the running total, then 
        // totalValue and initialValue are equal when CompareExchange
        // compares them, and computedValue is stored in totalValue.
        // CompareExchange returns the value that was in totalValue
        // before the update, which is equal to initialValue, so the 
        // loop ends.

        // The function returns computedValue, not totalValue, because
        // totalValue could be changed by another thread between
        // the time the loop ends and the function returns.
        return computedValue;
    }
}

public class Test
{
    // Create an instance of the ThreadSafe class to test.
    private static ThreadSafe ts = new ThreadSafe();
    private static double control;

    private static Random r = new Random();
    private static ManualResetEvent mre = new ManualResetEvent(false);

    public static void Main()
    {
        // Create two threads, name them, and start them. The
        // thread will block on mre.
        Thread t1 = new Thread(TestThread);
        t1.Name = "Thread 1";
        t1.Start();
        Thread t2 = new Thread(TestThread);
        t2.Name = "Thread 2";
        t2.Start();

        // Now let the threads begin adding random numbers to 
        // the total.
        mre.Set();
        
        // Wait until all the threads are done.
        t1.Join();
        t2.Join();

        Console.WriteLine("Thread safe: {0}  Ordinary Double: {1}", 
            ts.Total, control);
    }

    private static void TestThread()
    {
        // Wait until the signal.
        mre.WaitOne();

        for(int i = 1; i <= 1000000; i++)
        {
            // Add to the running total in the ThreadSafe instance, and
            // to an ordinary double.
            //
            double testValue = r.NextDouble();
            control += testValue;
            ts.AddToTotal(testValue);
        }
    }
}

/* On a dual-processor computer, this code example produces output 
   similar to the following:

Thread safe: 998068.049623744  Ordinary Double: 759775.417190589
 */
' This example demonstrates a thread-safe method that adds to a
' running total.  
Imports System.Threading

Public Class ThreadSafe
    ' Field totalValue contains a running total that can be updated
    ' by multiple threads. It must be protected from unsynchronized 
    ' access.
    Private totalValue As Double = 0.0

    ' The Total property returns the running total.
    Public ReadOnly Property Total As Double
        Get
            Return totalValue
        End Get
    End Property

    ' AddToTotal safely adds a value to the running total.
    Public Function AddToTotal(ByVal addend As Double) As Double
        Dim initialValue, computedValue As Double
        Do
            ' Save the current running total in a local variable.
            initialValue = totalValue

            ' Add the new value to the running total.
            computedValue = initialValue + addend

            ' CompareExchange compares totalValue to initialValue. If
            ' they are not equal, then another thread has updated the
            ' running total since this loop started. CompareExchange
            ' does not update totalValue. CompareExchange returns the
            ' contents of totalValue, which do not equal initialValue,
            ' so the loop executes again.
        Loop While initialValue <> Interlocked.CompareExchange( _
            totalValue, computedValue, initialValue)
        ' If no other thread updated the running total, then 
        ' totalValue and initialValue are equal when CompareExchange
        ' compares them, and computedValue is stored in totalValue.
        ' CompareExchange returns the value that was in totalValue
        ' before the update, which is equal to initialValue, so the 
        ' loop ends.

        ' The function returns computedValue, not totalValue, because
        ' totalValue could be changed by another thread between
        ' the time the loop ends and the function returns.
        Return computedValue
    End Function
End Class

Public Class Test
    ' Create an instance of the ThreadSafe class to test.
    Private Shared ts As New ThreadSafe()
    Private Shared control As Double

    Private Shared r As New Random()
    Private Shared mre As New ManualResetEvent(false)

    <MTAThread> _
    Public Shared Sub Main()
        ' Create two threads, name them, and start them. The
        ' threads will block on mre.
        Dim t1 As New Thread(AddressOf TestThread)
        t1.Name = "Thread 1"
        t1.Start()
        Dim t2 As New Thread(AddressOf TestThread)
        t2.Name = "Thread 2"
        t2.Start()

        ' Now let the threads begin adding random numbers to 
        ' the total.
        mre.Set()
        
        ' Wait until all the threads are done.
        t1.Join()
        t2.Join()

        Console.WriteLine("Thread safe: {0}  Ordinary Double: {1}", ts.Total, control)
    End Sub

    Private Shared Sub TestThread()
        ' Wait until the signal.
        mre.WaitOne()

        For i As Integer = 1 to 1000000
            ' Add to the running total in the ThreadSafe instance, and
            ' to an ordinary double.
            '
            Dim testValue As Double = r.NextDouble
            control += testValue
            ts.AddToTotal(testValue)
        Next
    End Sub
End Class

' On a dual-processor computer, this code example produces output 
' similar to the following:
'
'Thread safe: 998068.049623744  Ordinary Double: 759775.417190589

Comentários

Se comparand e o valor em location1 forem iguais, será value armazenado em location1. Caso contrário, nenhuma operação será executada. As operações de comparação e troca são executadas como uma operação atômica. O valor retornado de CompareExchange é o valor original em location1, independentemente de a troca ocorrer ou não.

Confira também

Aplica-se a

CompareExchange(Byte, Byte, Byte)

public:
 static System::Byte CompareExchange(System::Byte % location1, System::Byte value, System::Byte comparand);
public static byte CompareExchange (ref byte location1, byte value, byte comparand);
static member CompareExchange : byte * byte * byte -> byte
Public Shared Function CompareExchange (ByRef location1 As Byte, value As Byte, comparand As Byte) As Byte

Parâmetros

location1
Byte
value
Byte
comparand
Byte

Retornos

Aplica-se a

CompareExchange(IntPtr, IntPtr, IntPtr)

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

Compara dois ponteiros ou identificadores específicos da plataforma quanto à igualdade e, se eles são iguais, substitui o primeiro.

public:
 static IntPtr CompareExchange(IntPtr % location1, IntPtr value, IntPtr comparand);
public static IntPtr CompareExchange (ref IntPtr location1, IntPtr value, IntPtr comparand);
static member CompareExchange : nativeint * nativeint * nativeint -> nativeint
Public Shared Function CompareExchange (ByRef location1 As IntPtr, value As IntPtr, comparand As IntPtr) As IntPtr

Parâmetros

location1
IntPtr

nativeint

O IntPtr de destino, cujo valor é comparado com o valor de comparand e possivelmente substituído por value.

value
IntPtr

nativeint

O IntPtr que substitui o valor de destino quando a comparação resulta em igualdade.

comparand
IntPtr

nativeint

O IntPtr comparado ao valor em location1.

Retornos

IntPtr

nativeint

O valor original em location1.

Exceções

O endereço de location1 é um ponteiro nulo.

Comentários

Se comparand e o valor em location1 forem iguais, será value armazenado em location1. Caso contrário, nenhuma operação será executada. As operações de comparação e troca são executadas como uma operação atômica. O valor retornado desse método é o valor original em location1, independentemente de a troca ocorrer ou não.

Observação

IntPtr é um tipo específico da plataforma.

Confira também

Aplica-se a

CompareExchange<T>(T, T, T)

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

Compara duas instâncias do tipo de referência T especificado em relação à igualdade e, se elas forem iguais, substitui a primeira.

public:
generic <typename T>
 where T : class static T CompareExchange(T % location1, T value, T comparand);
public static T CompareExchange<T> (ref T location1, T value, T comparand) where T : class;
[System.Runtime.InteropServices.ComVisible(false)]
public static T CompareExchange<T> (ref T location1, T value, T comparand) where T : class;
static member CompareExchange : 'T * 'T * 'T -> 'T (requires 'T : null)
[<System.Runtime.InteropServices.ComVisible(false)>]
static member CompareExchange : 'T * 'T * 'T -> 'T (requires 'T : null)
Public Shared Function CompareExchange(Of T As Class) (ByRef location1 As T, value As T, comparand As T) As T

Parâmetros de tipo

T

O tipo a ser usado para location1, value e comparand. Esse tipo deve ser um tipo de referência.

Parâmetros

location1
T

O destino, cujo valor é comparado por referência com comparand e possivelmente substituído. Esse é um parâmetro de referência (ref no C# e ByRef no Visual Basic).

value
T

O valor que substitui o valor de destino quando a comparação pela referência resulta em igualdade.

comparand
T

O valor que é comparado pela referência com o valor em location1.

Retornos

T

O valor original em location1.

Atributos

Exceções

O endereço de location1 é um ponteiro nulo.

Comentários

Se comparand e o valor em location1 forem iguais por referência, será value armazenado em location1. Caso contrário, nenhuma operação será executada. A comparação e a troca são executadas como uma operação atômica. O valor retornado desse método é o valor original em location1, independentemente de a troca ocorrer ou não.

Esse método só dá suporte a tipos de referência. Há sobrecargas do método para os tipos de CompareExchange valor , Int64, IntPtr, Singlee Double, mas não há suporte para outros tipos de Int32valor.

Observação

Essa sobrecarga de método é preferível à sobrecarga do CompareExchange(Object, Object, Object) método, pois este último requer que o objeto de destino seja acessado com limite tardio.

Aplica-se a