Aracılığıyla paylaş


ThreadStaticAttribute Sınıf

Tanım

Statik alanın değerinin her iş parçacığı için benzersiz olduğunu gösterir.

public ref class ThreadStaticAttribute : Attribute
[System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)]
public class ThreadStaticAttribute : Attribute
[System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)]
[System.Serializable]
public class ThreadStaticAttribute : Attribute
[System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)]
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class ThreadStaticAttribute : Attribute
[<System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)>]
type ThreadStaticAttribute = class
    inherit Attribute
[<System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)>]
[<System.Serializable>]
type ThreadStaticAttribute = class
    inherit Attribute
[<System.AttributeUsage(System.AttributeTargets.Field, Inherited=false)>]
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type ThreadStaticAttribute = class
    inherit Attribute
Public Class ThreadStaticAttribute
Inherits Attribute
Devralma
ThreadStaticAttribute
Öznitelikler

Örnekler

Aşağıdaki örnek rastgele bir sayı oluşturucu oluşturur, ana iş parçacığına ek olarak on iş parçacığı oluşturur ve sonra her iş parçacığında iki milyon rastgele sayı oluşturur. İş parçacığı başına rastgele sayıların toplamını ve sayısını hesaplamak için özniteliğini kullanır ThreadStaticAttribute . Ayrıca, previous abnormalrastgele sayı oluşturucusunun bozulmasını algılamasını sağlayan ve olmak üzere iki ek iş parçacığı başına alan tanımlar.

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.
open System
open System.Threading

type Example() =
    [<ThreadStatic; DefaultValue>] 
    static val mutable private previous : double

    [<ThreadStatic; DefaultValue>] 
    static val mutable private sum : double
    
    [<ThreadStatic; DefaultValue>] 
    static val mutable private calls : int

    [<ThreadStatic; DefaultValue>] 
    static val mutable private abnormal : bool
   
    static let mutable totalNumbers = 0
    static let countdown = new CountdownEvent(1)
    static let lockObj = obj ()
    let rand = Random()


    member this.Execute() =
        for threads = 1 to 10 do
            let newThread = new Thread(ThreadStart this.GetRandomNumbers)
            countdown.AddCount()
            newThread.Name <- threads.ToString()
            newThread.Start()
        this.GetRandomNumbers()
        countdown.Wait()
        printfn $"{totalNumbers:N0} random numbers were generated."

    member _.GetRandomNumbers() =
        let mutable i = 0
        while i < 2000000 do
            lock lockObj (fun () ->
                let result = rand.NextDouble()
                Example.calls <- Example.calls + 1
                Interlocked.Increment &totalNumbers |> ignore
                // We should never get the same random number twice.
                if result = Example.previous then
                    Example.abnormal <- true
                    i <- 2000001 // break
                else
                    Example.previous <- result
                    Example.sum <- Example.sum + result )
            i <- i + 1
        // get last result
        if Example.abnormal then
            printfn $"Result is {Example.previous} in {Thread.CurrentThread.Name}"
        
        printfn $"Thread {Thread.CurrentThread.Name} finished random number generation."
        printfn $"Sum = {Example.sum:N4}, Mean = {Example.sum / float Example.calls:N4}, n = {Example.calls:N0}\n"
        countdown.Signal() |> ignore

let ex = Example()
Thread.CurrentThread.Name <- "Main"
ex.Execute()

// 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.

Örnekte C# dilinde deyimi, lock F# işlevi ve SyncLock rastgele sayı oluşturucuya erişimi eşitlemek için Visual Basic yapısı kullanılırlock. Bu, rastgele sayı oluşturucunun bozulmasını önler ve bu da genellikle sonraki tüm çağrılar için sıfır değerini döndürmesine neden olur.

Örnek ayrıca, her iş parçacığının CountdownEvent toplam çağrı sayısını görüntülemeden önce rastgele sayılar üretmeyi tamamladığından emin olmak için sınıfını kullanır. Aksi takdirde, ana iş parçacığı, oluşturulan ek iş parçacıklarından önce yürütmeyi tamamlarsa, yöntem çağrılarının toplam sayısı için yanlış bir değer görüntüler.

Açıklamalar

static ile ThreadStaticAttribute işaretlenen bir alan iş parçacıkları arasında paylaşılmaz. Yürütülen her iş parçacığı, alanın ayrı bir örneğine sahiptir ve bu alan için değerleri bağımsız olarak ayarlar ve alır. Alana farklı bir iş parçacığında erişilirse, farklı bir değer içerir.

Özniteliği bir alana uygulamanın ThreadStaticAttribute yanı sıra, bunu bir static alan (C# veya F# dilinde) veya alan Shared (Visual Basic) olarak da tanımlamanız gerektiğini unutmayın.

Not

ile ThreadStaticAttributeişaretlenmiş alanlar için başlangıç değerlerini belirtmeyin, çünkü bu tür bir başlatma yalnızca bir kez, sınıf oluşturucu yürütür ve bu nedenle yalnızca bir iş parçacığını etkiler. Bir başlangıç değeri belirtmezseniz, bir değer türüyse veya bir başvuru türüyse, alanın varsayılan değerine başlatılmasını null sağlayabilirsiniz.

Bu özniteliği olduğu gibi kullanın ve ondan türetmayın.

Öznitelikleri kullanma hakkında daha fazla bilgi için bkz . Öznitelikler.

Oluşturucular

ThreadStaticAttribute()

ThreadStaticAttribute sınıfının yeni bir örneğini başlatır.

Özellikler

TypeId

Türetilmiş bir sınıfta uygulandığında, bu Attributeiçin benzersiz bir tanımlayıcı alır.

(Devralındığı yer: Attribute)

Yöntemler

Equals(Object)

Bu örneğin belirtilen bir nesneye eşit olup olmadığını gösteren bir değeri döndürür.

(Devralındığı yer: Attribute)
GetHashCode()

Bu örneğe ilişkin karma kodu döndürür.

(Devralındığı yer: Attribute)
GetType()

Type Geçerli örneğini alır.

(Devralındığı yer: Object)
IsDefaultAttribute()

Türetilmiş bir sınıfta geçersiz kılındığında, bu örneğin değerinin türetilmiş sınıf için varsayılan değer olup olmadığını gösterir.

(Devralındığı yer: Attribute)
Match(Object)

Türetilmiş bir sınıfta geçersiz kılındığında, bu örneğin belirtilen bir nesneye eşit olup olmadığını gösteren bir değer döndürür.

(Devralındığı yer: Attribute)
MemberwiseClone()

Geçerli Objectöğesinin sığ bir kopyasını oluşturur.

(Devralındığı yer: Object)
ToString()

Geçerli nesneyi temsil eden dizeyi döndürür.

(Devralındığı yer: Object)

Belirtik Arabirim Kullanımları

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

Bir ad kümesini karşılık gelen bir dağıtma tanımlayıcısı kümesine eşler.

(Devralındığı yer: Attribute)
_Attribute.GetTypeInfo(UInt32, UInt32, IntPtr)

Bir arabirimin tür bilgilerini almak için kullanılabilecek bir nesnenin tür bilgilerini alır.

(Devralındığı yer: Attribute)
_Attribute.GetTypeInfoCount(UInt32)

Bir nesnenin sağladığı tür bilgisi arabirimlerinin sayısını alır (0 ya da 1).

(Devralındığı yer: Attribute)
_Attribute.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

Bir nesne tarafından sunulan özelliklere ve yöntemlere erişim sağlar.

(Devralındığı yer: Attribute)

Şunlara uygulanır

Ayrıca bkz.