ThreadStaticAttribute Classe

Definição

Indica se o valor de um campo estático é exclusivo para cada thread.Indicates that the value of a static field is unique for each thread.

public ref class ThreadStaticAttribute : Attribute
[System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)]
[System.Runtime.InteropServices.ComVisible(true)]
[System.Serializable]
public class ThreadStaticAttribute : Attribute
type ThreadStaticAttribute = class
    inherit Attribute
Public Class ThreadStaticAttribute
Inherits Attribute
Herança
ThreadStaticAttribute
Atributos

Exemplos

O exemplo a seguir instancia um gerador de números aleatórios, cria dez threads além do thread principal e, em seguida, gera 2 milhões números aleatórios em cada thread.The following example instantiates a random number generator, creates ten threads in addition to the main thread, and then generates two million random numbers in each thread. Ele usa o ThreadStaticAttribute atributo para calcular a soma e a contagem de números aleatórios por thread.It uses the ThreadStaticAttribute attribute to calculate the sum and the count of random numbers per thread. Ele também define dois campos previous adicionais por thread e abnormal, que permitem que ele detecte a corrupção do gerador de números aleatórios.It also defines two additional per-thread fields, previous and abnormal, that allows it to detect corruption of the random number generator.

using System;
using System.Threading;

public class Example
{
   [ThreadStatic] static double previous = 0.0;
   [ThreadStatic] static double sum = 0.0;
   [ThreadStatic] static int calls = 0;
   [ThreadStatic] static bool abnormal;
   static int totalNumbers = 0;
   static CountdownEvent countdown;
   private static Object lockObj;
   Random rand;
   
   public Example()
   { 
      rand = new Random();
      lockObj = new Object();
      countdown = new CountdownEvent(1);
   } 

   public static void Main()
   {
      Example ex = new Example();
      Thread.CurrentThread.Name = "Main";
      ex.Execute();
      countdown.Wait();
      Console.WriteLine("{0:N0} random numbers were generated.", totalNumbers);
   }

   private void Execute()
   {   
      for (int threads = 1; threads <= 10; threads++)
      {
         Thread newThread = new Thread(new ThreadStart(this.GetRandomNumbers));
         countdown.AddCount();
         newThread.Name = threads.ToString();
         newThread.Start();
      }
      this.GetRandomNumbers();
   }

   private void GetRandomNumbers()
   {
      double result = 0.0;
      
       
      for (int ctr = 0; ctr < 2000000; ctr++)
      {
         lock (lockObj) {
            result = rand.NextDouble();
            calls++;
            Interlocked.Increment(ref totalNumbers);
            // We should never get the same random number twice.
            if (result == previous) {
               abnormal = true;
               break;
            }
            else {
               previous = result;
               sum += result;
            }   
         }
      }
      // get last result
      if (abnormal)
         Console.WriteLine("Result is {0} in {1}", previous, Thread.CurrentThread.Name);
       
      Console.WriteLine("Thread {0} finished random number generation.", Thread.CurrentThread.Name);
      Console.WriteLine("Sum = {0:N4}, Mean = {1:N4}, n = {2:N0}\n", sum, sum/calls, calls);        
      countdown.Signal();
   }
}
// The example displays output similar to the following:
//    Thread 1 finished random number generation.
//    Sum = 1,000,556.7483, Mean = 0.5003, n = 2,000,000
//    
//    Thread 6 finished random number generation.
//    Sum = 999,704.3865, Mean = 0.4999, n = 2,000,000
//    
//    Thread 2 finished random number generation.
//    Sum = 999,680.8904, Mean = 0.4998, n = 2,000,000
//    
//    Thread 10 finished random number generation.
//    Sum = 999,437.5132, Mean = 0.4997, n = 2,000,000
//    
//    Thread 8 finished random number generation.
//    Sum = 1,000,663.7789, Mean = 0.5003, n = 2,000,000
//    
//    Thread 4 finished random number generation.
//    Sum = 999,379.5978, Mean = 0.4997, n = 2,000,000
//    
//    Thread 5 finished random number generation.
//    Sum = 1,000,011.0605, Mean = 0.5000, n = 2,000,000
//    
//    Thread 9 finished random number generation.
//    Sum = 1,000,637.4556, Mean = 0.5003, n = 2,000,000
//    
//    Thread Main finished random number generation.
//    Sum = 1,000,676.2381, Mean = 0.5003, n = 2,000,000
//    
//    Thread 3 finished random number generation.
//    Sum = 999,951.1025, Mean = 0.5000, n = 2,000,000
//    
//    Thread 7 finished random number generation.
//    Sum = 1,000,844.5217, Mean = 0.5004, n = 2,000,000
//    
//    22,000,000 random numbers were generated.
Imports System.Threading

Public Class Example
   <ThreadStatic> Shared previous As Double = 0.0
   <ThreadStatic> Shared sum As Double = 0.0
   <ThreadStatic> Shared calls As Integer = 0
   <ThreadStatic> Shared abnormal As Boolean
   Shared totalNumbers As Integer = 0
   Shared countdown As CountdownEvent
   Private Shared lockObj As Object
   Dim rand As Random

   Public Sub New()
      rand = New Random()
      lockObj = New Object()
      countdown = New CountdownEvent(1)
   End Sub

   Public Shared Sub Main()
      Dim ex As New Example()
      Thread.CurrentThread.Name = "Main"
      ex.Execute()
      countdown.Wait()
      Console.WriteLine("{0:N0} random numbers were generated.", totalNumbers)
   End Sub

   Private Sub Execute()
      For threads As Integer = 1 To 10
         Dim newThread As New Thread(New ThreadStart(AddressOf GetRandomNumbers))
         countdown.AddCount()
         newThread.Name = threads.ToString()
         newThread.Start()
      Next
      Me.GetRandomNumbers()
   End Sub

   Private Sub GetRandomNumbers()
      Dim result As Double = 0.0
      
       
      For ctr As Integer = 1 To 2000000
         SyncLock lockObj
            result = rand.NextDouble()
            calls += 1
            Interlocked.Increment(totalNumbers)
            ' We should never get the same random number twice.
            If result = previous Then
               abnormal = True
               Exit For
            Else
               previous = result
               sum += result
            End If   
         End SyncLock
      Next
      ' Get last result.
      If abnormal Then
         Console.WriteLine("Result is {0} in {1}", previous, Thread.CurrentThread.Name)
      End If       
      
      Console.WriteLine("Thread {0} finished random number generation.", Thread.CurrentThread.Name)
      Console.WriteLine("Sum = {0:N4}, Mean = {1:N4}, n = {2:N0}", sum, sum/calls, calls)
      Console.WriteLine()        
      countdown.Signal()
   End Sub
End Class
' The example displays output similar to the following:
'    Thread 1 finished random number generation.
'    Sum = 1,000,556.7483, Mean = 0.5003, n = 2,000,000
'    
'    Thread 6 finished random number generation.
'    Sum = 999,704.3865, Mean = 0.4999, n = 2,000,000
'    
'    Thread 2 finished random number generation.
'    Sum = 999,680.8904, Mean = 0.4998, n = 2,000,000
'    
'    Thread 10 finished random number generation.
'    Sum = 999,437.5132, Mean = 0.4997, n = 2,000,000
'    
'    Thread 8 finished random number generation.
'    Sum = 1,000,663.7789, Mean = 0.5003, n = 2,000,000
'    
'    Thread 4 finished random number generation.
'    Sum = 999,379.5978, Mean = 0.4997, n = 2,000,000
'    
'    Thread 5 finished random number generation.
'    Sum = 1,000,011.0605, Mean = 0.5000, n = 2,000,000
'    
'    Thread 9 finished random number generation.
'    Sum = 1,000,637.4556, Mean = 0.5003, n = 2,000,000
'    
'    Thread Main finished random number generation.
'    Sum = 1,000,676.2381, Mean = 0.5003, n = 2,000,000
'    
'    Thread 3 finished random number generation.
'    Sum = 999,951.1025, Mean = 0.5000, n = 2,000,000
'    
'    Thread 7 finished random number generation.
'    Sum = 1,000,844.5217, Mean = 0.5004, n = 2,000,000
'    
'    22,000,000 random numbers were generated.

O exemplo usa a lock instrução em C# e a SyncLock construção em Visual Basic para sincronizar o acesso ao gerador de número aleatório.The example uses the lock statement in C# and the SyncLock construct in Visual Basic to synchronize access to the random number generator. Isso evita a corrupção do gerador de número aleatório, que normalmente resulta em seu retorno de um valor zero para todas as chamadas subsequentes.This prevents corruption of the random number generator, which typically results in its returning a value of zero for all subsequent calls.

O exemplo também usa a CountdownEvent classe para garantir que cada thread tenha terminado de gerar números aleatórios antes de exibir o número total de chamadas.The example also uses the CountdownEvent class to ensure that each thread has finished generating random numbers before it displays the total number of calls. Caso contrário, se o thread principal concluir a execução antes dos threads adicionais que ele gerar, ele exibirá um valor impreciso para o número total de chamadas de método.Otherwise, if the main thread completes execution before the additional threads that it spawns, it displays an inaccurate value for the total number of method calls.

Comentários

Um static campo marcado com ThreadStaticAttribute não é compartilhado entre threads.A static field marked with ThreadStaticAttribute is not shared between threads. Cada thread em execução tem uma instância separada do campo e define e obtém valores de forma independente para esse campo.Each executing thread has a separate instance of the field, and independently sets and gets values for that field. Se o campo for acessado em um thread diferente, ele conterá um valor diferente.If the field is accessed on a different thread, it will contain a different value.

Observe que, além de aplicar o ThreadStaticAttribute atributo a um campo, você também deve defini-lo como static um campo ( C#em) ou Shared um campo (em Visual Basic).Note that in addition to applying the ThreadStaticAttribute attribute to a field, you must also define it as a static field (in C#) or a Shared field (in Visual Basic).

Observação

Não especifique valores iniciais para campos marcados com ThreadStaticAttribute, porque essa inicialização ocorre apenas uma vez, quando o construtor de classe é executado e, portanto, afeta apenas um thread.Do not specify initial values for fields marked with ThreadStaticAttribute, because such initialization occurs only once, when the class constructor executes, and therefore affects only one thread. Se você não especificar um valor inicial, poderá contar com o campo que está sendo inicializado para seu valor padrão, se for um tipo de valor, null ou se for um tipo de referência.If you do not specify an initial value, you can rely on the field being initialized to its default value if it is a value type, or to null if it is a reference type.

Use esse atributo como ele está e não derive dele.Use this attribute as it is, and do not derive from it.

Para obter mais informações sobre como usar atributos, consulte atributos.For more information about using attributes, see Attributes.

Construtores

ThreadStaticAttribute()

Inicializa uma nova instância da classe ThreadStaticAttribute.Initializes a new instance of the ThreadStaticAttribute class.

Propriedades

TypeId

Quando implementado em uma classe derivada, obtém um identificador exclusivo para este Attribute.When implemented in a derived class, gets a unique identifier for this Attribute.

(Herdado de Attribute)

Métodos

Equals(Object)

Retorna um valor que indica se essa instância é igual a um objeto especificado.Returns a value that indicates whether this instance is equal to a specified object.

(Herdado de Attribute)
GetHashCode()

Retorna o código hash para essa instância.Returns the hash code for this instance.

(Herdado de Attribute)
GetType()

Obtém o Type da instância atual.Gets the Type of the current instance.

(Herdado de Object)
IsDefaultAttribute()

Quando substituído em uma classe derivada, indica se o valor dessa instância é o valor padrão para a classe derivada.When overridden in a derived class, indicates whether the value of this instance is the default value for the derived class.

(Herdado de Attribute)
Match(Object)

Quando substituído em uma classe derivada, retorna um valor que indica se essa instância é igual a um objeto especificado.When overridden in a derived class, returns a value that indicates whether this instance equals a specified object.

(Herdado de Attribute)
MemberwiseClone()

Cria uma cópia superficial do Object atual.Creates a shallow copy of the current Object.

(Herdado de Object)
ToString()

Retorna uma cadeia de caracteres que representa o objeto atual.Returns a string that represents the current object.

(Herdado de Object)

Implantações explícitas de interface

_Attribute.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr)

Mapeia um conjunto de nomes para um conjunto correspondente de identificadores de expedição.Maps a set of names to a corresponding set of dispatch identifiers.

(Herdado de Attribute)
_Attribute.GetTypeInfo(UInt32, UInt32, IntPtr)

Recupera as informações de tipo para um objeto, que pode ser usado para obter as informações de tipo para uma interface.Retrieves the type information for an object, which can be used to get the type information for an interface.

(Herdado de Attribute)
_Attribute.GetTypeInfoCount(UInt32)

Retorna o número de interfaces de informações do tipo que um objeto fornece (0 ou 1).Retrieves the number of type information interfaces that an object provides (either 0 or 1).

(Herdado de Attribute)
_Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

Fornece acesso a propriedades e métodos expostos por um objeto.Provides access to properties and methods exposed by an object.

(Herdado de Attribute)

Aplica-se a

Veja também