ThreadStaticAttribute ThreadStaticAttribute ThreadStaticAttribute ThreadStaticAttribute Class

정의

정적 필드의 값이 각 스레드에 대해 고유함을 나타냅니다.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
상속
ThreadStaticAttributeThreadStaticAttributeThreadStaticAttributeThreadStaticAttribute
특성

예제

난수 생성기를 인스턴스화하고 주 스레드에서 외에도 10 개 스레드를 만드는 다음 각 스레드에서 두 백만 난수를 생성 하는 다음 예제에서는 합니다.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. 사용 된 ThreadStaticAttribute 스레드당 임의 숫자의 개수 및 합계를 계산 하는 특성입니다.It uses the ThreadStaticAttribute attribute to calculate the sum and the count of random numbers per thread. 또한 두 개의 추가 스레드가 필드 정의 previousabnormal, 난수 생성기의 손상을 검색할 수 있도록 합니다.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.

이 예제에서는 사용 합니다 lock C#의 문은 및 SyncLock 난수 생성기에 대 한 액세스를 동기화 하는 Visual Basic에서 생성 합니다.The example uses the lock statement in C# and the SyncLock construct in Visual Basic to synchronize access to the random number generator. 이 일반적으로 해당 반환 값이 모든 후속 호출에 대해 0에서 임의의 수 생성기의 손상을 방지 합니다.This prevents corruption of the random number generator, which typically results in its returning a value of zero for all subsequent calls.

또한이 예제에서는 CountdownEvent 난수를 생성 하 여 호출의 총 수를 표시 하기 전에 각 스레드가 완료 되었는지 확인 하는 클래스입니다.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. 이 고, 그렇지 main 메서드가 추가 스레드는 생성 하기 전에 실행이 완료 되는 경우 메서드 호출의 총 수에 대 한 부정확 한 값을 표시 합니다.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.

설명

A static 표시 된 필드 ThreadStaticAttribute 스레드 간에 공유 되지 않습니다.A static field marked with ThreadStaticAttribute is not shared between threads. 각 실행 스레드에 필드의 별도 인스턴스가 및 독립적으로 설정 하 고이 해당 필드에 대 한 값을 가져옵니다 만듭니다.Each executing thread has a separate instance of the field, and independently sets and gets values for that field. 필드를 다른 스레드에서 액세스 하는 경우 다른 값을 포함 됩니다.If the field is accessed on a different thread, it will contain a different value.

적용 하는 것 외에도 유의 합니다 ThreadStaticAttribute 특성 필드를 정의 해야 합니다도를 static 필드 (C#) 또는 Shared 필드 (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).

참고

로 표시 된 필드에 대 한 초기 값을 지정 하지 않으면 ThreadStaticAttribute이므로 이러한 초기화는 한 번만 클래스 생성자 실행 되 고 하나의 스레드만 영향을 때 발생 합니다.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. 값 형식인 또는를 기본값으로 초기화 되는 필드 의존할 수 있는 초기 값을 지정 하지 않으면 경우 null 참조 형식인 경우.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 this attribute as it is, and do not derive from it.

특성을 사용 하는 방법에 대 한 자세한 내용은 참조 하세요. 특성합니다.For more information about using attributes, see Attributes.

생성자

ThreadStaticAttribute() ThreadStaticAttribute() ThreadStaticAttribute() ThreadStaticAttribute()

ThreadStaticAttribute 클래스의 새 인스턴스를 초기화합니다.Initializes a new instance of the ThreadStaticAttribute class.

메서드

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

이 인스턴스가 지정한 개체와 같은지를 나타내는 값을 반환합니다.Returns a value that indicates whether this instance is equal to a specified object.

(Inherited from Attribute)
GetHashCode() GetHashCode() GetHashCode() GetHashCode()

이 인스턴스의 해시 코드를 반환합니다.Returns the hash code for this instance.

(Inherited from Attribute)
GetType() GetType() GetType() GetType()

현재 인스턴스의 Type을 가져옵니다.Gets the Type of the current instance.

(Inherited from Object)
IsDefaultAttribute() IsDefaultAttribute() IsDefaultAttribute() IsDefaultAttribute()

파생 클래스에서 재정의된 경우 이 인스턴스 값이 파생 클래스에 대한 기본값인지 여부를 표시합니다.When overridden in a derived class, indicates whether the value of this instance is the default value for the derived class.

(Inherited from Attribute)
Match(Object) Match(Object) Match(Object) Match(Object)

파생 클래스에서 재정의된 경우 이 인스턴스가 지정된 개체와 같은지 여부를 나타내는 값을 반환합니다.When overridden in a derived class, returns a value that indicates whether this instance equals a specified object.

(Inherited from Attribute)
MemberwiseClone() MemberwiseClone() MemberwiseClone() MemberwiseClone()

현재 Object의 단순 복사본을 만듭니다.Creates a shallow copy of the current Object.

(Inherited from Object)
ToString() ToString() ToString() ToString()

현재 개체를 나타내는 문자열을 반환합니다.Returns a string that represents the current object.

(Inherited from Object)

명시적 인터페이스 구현

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

이름 집합을 해당하는 디스패치 식별자 집합에 매핑합니다.Maps a set of names to a corresponding set of dispatch identifiers.

(Inherited from Attribute)
_Attribute.GetTypeInfo(UInt32, UInt32, IntPtr) _Attribute.GetTypeInfo(UInt32, UInt32, IntPtr) _Attribute.GetTypeInfo(UInt32, UInt32, IntPtr) _Attribute.GetTypeInfo(UInt32, UInt32, IntPtr)

인터페이스의 형식 정보를 가져오는 데 사용할 수 있는 개체의 형식 정보를 검색합니다.Retrieves the type information for an object, which can be used to get the type information for an interface.

(Inherited from Attribute)
_Attribute.GetTypeInfoCount(UInt32) _Attribute.GetTypeInfoCount(UInt32) _Attribute.GetTypeInfoCount(UInt32) _Attribute.GetTypeInfoCount(UInt32)

개체에서 제공하는 형식 정보 인터페이스의 수를 검색합니다(0 또는 1).Retrieves the number of type information interfaces that an object provides (either 0 or 1).

(Inherited from Attribute)
_Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr) _Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr) _Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr) _Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

개체에서 노출하는 메서드와 속성에 대한 액세스를 제공합니다.Provides access to properties and methods exposed by an object.

(Inherited from Attribute)

속성

TypeId TypeId TypeId TypeId

파생 클래스에서 구현된 경우 이 Attribute에 대한 고유 식별자를 가져옵니다.When implemented in a derived class, gets a unique identifier for this Attribute.

(Inherited from Attribute)

적용 대상

추가 정보