Monitor Sınıf

Tanım

Nesnelere erişimi eşitleyen bir mekanizma sağlar.Provides a mechanism that synchronizes access to objects.

public ref class Monitor abstract sealed
public ref class Monitor sealed
public static class Monitor
public sealed class Monitor
[System.Runtime.InteropServices.ComVisible(true)]
public static class Monitor
type Monitor = class
[<System.Runtime.InteropServices.ComVisible(true)>]
type Monitor = class
Public Class Monitor
Public NotInheritable Class Monitor
Devralma
Monitor
Öznitelikler

Örnekler

Aşağıdaki örnek, sınıfı Monitor tarafından temsil edilen rastgele sayı oluşturucusunun tek bir örneğine erişimi eşleştirmek için sınıfını kullanır Random .The following example uses the Monitor class to synchronize access to a single instance of a random number generator represented by the Random class. Örnek, her biri bir iş parçacığı havuzu iş parçacığında zaman uyumsuz olarak yürütülen on görev oluşturur.The example creates ten tasks, each of which executes asynchronously on a thread pool thread. Her görev 10.000 rastgele sayı üretir, ortalamasını hesaplar ve üretilen rastgele sayıların sayısını ve bunların toplamlarını hesaplayan iki yordam düzeyi değişkeni güncelleştirir.Each task generates 10,000 random numbers, calculates their average, and updates two procedure-level variables that maintain a running total of the number of random numbers generated and their sum. Tüm görevler yürütüldükten sonra, bu iki değer daha sonra genel ortalaması hesaplamak için kullanılır.After all tasks have executed, these two values are then used to calculate the overall mean.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      List<Task> tasks = new List<Task>();
      Random rnd = new Random();
      long total = 0;
      int n = 0;
      
      for (int taskCtr = 0; taskCtr < 10; taskCtr++)
         tasks.Add(Task.Run( () => {  int[] values = new int[10000];
                                      int taskTotal = 0;
                                      int taskN = 0;
                                      int ctr = 0;
                                      Monitor.Enter(rnd);
                                         // Generate 10,000 random integers
                                         for (ctr = 0; ctr < 10000; ctr++)
                                            values[ctr] = rnd.Next(0, 1001);
                                      Monitor.Exit(rnd);
                                      taskN = ctr;
                                      foreach (var value in values)
                                         taskTotal += value;

                                      Console.WriteLine("Mean for task {0,2}: {1:N2} (N={2:N0})",
                                                        Task.CurrentId, (taskTotal * 1.0)/taskN,
                                                        taskN);
                                      Interlocked.Add(ref n, taskN);
                                      Interlocked.Add(ref total, taskTotal);
                                    } ));
      try {
         Task.WaitAll(tasks.ToArray());
         Console.WriteLine("\nMean for all tasks: {0:N2} (N={1:N0})",
                           (total * 1.0)/n, n);
      }
      catch (AggregateException e) {
         foreach (var ie in e.InnerExceptions)
            Console.WriteLine("{0}: {1}", ie.GetType().Name, ie.Message);
      }
   }
}
// The example displays output like the following:
//       Mean for task  1: 499.04 (N=10,000)
//       Mean for task  2: 500.42 (N=10,000)
//       Mean for task  3: 499.65 (N=10,000)
//       Mean for task  8: 502.59 (N=10,000)
//       Mean for task  5: 502.75 (N=10,000)
//       Mean for task  4: 494.88 (N=10,000)
//       Mean for task  7: 499.22 (N=10,000)
//       Mean for task 10: 496.45 (N=10,000)
//       Mean for task  6: 499.75 (N=10,000)
//       Mean for task  9: 502.79 (N=10,000)
//
//       Mean for all tasks: 499.75 (N=100,000)
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim tasks As New List(Of Task)()
      Dim rnd As New Random()
      Dim total As Long = 0
      Dim n As Integer = 0

      For taskCtr As Integer = 0 To 9
         tasks.Add(Task.Run( Sub()
                                Dim values(9999) As Integer
                                Dim taskTotal As Integer = 0
                                Dim taskN As Integer = 0
                                Dim ctr As Integer = 0
                                Monitor.Enter(rnd)
                                   ' Generate 10,000 random integers.
                                    For ctr = 0 To 9999
                                       values(ctr) = rnd.Next(0, 1001)
                                    Next
                                Monitor.Exit(rnd)
                                taskN = ctr
                                For Each value in values
                                   taskTotal += value
                                Next
                                    
                                Console.WriteLine("Mean for task {0,2}: {1:N2} (N={2:N0})",
                                                  Task.CurrentId, taskTotal/taskN,
                                                  taskN)
                                Interlocked.Add(n, taskN)
                                Interlocked.Add(total, taskTotal)
                             End Sub ))
      Next
      
      Try
         Task.WaitAll(tasks.ToArray())
         Console.WriteLine()
         Console.WriteLine("Mean for all tasks: {0:N2} (N={1:N0})",
                           (total * 1.0)/n, n)
      Catch e As AggregateException
         For Each ie In e.InnerExceptions
            Console.WriteLine("{0}: {1}", ie.GetType().Name, ie.Message)
         Next
      End Try
   End Sub
End Module
' The example displays output like the following:
'       Mean for task  1: 499.04 (N=10,000)
'       Mean for task  2: 500.42 (N=10,000)
'       Mean for task  3: 499.65 (N=10,000)
'       Mean for task  8: 502.59 (N=10,000)
'       Mean for task  5: 502.75 (N=10,000)
'       Mean for task  4: 494.88 (N=10,000)
'       Mean for task  7: 499.22 (N=10,000)
'       Mean for task 10: 496.45 (N=10,000)
'       Mean for task  6: 499.75 (N=10,000)
'       Mean for task  9: 502.79 (N=10,000)
'
'       Mean for all tasks: 499.75 (N=100,000)

İş parçacığı havuzu iş parçacığı üzerinde çalışan herhangi bir görevden erişilebildiğinden, değişkenlere erişim total ve n Ayrıca eşitlenmesi gerekir.Because they can be accessed from any task running on a thread pool thread, access to the variables total and n must also be synchronized. Interlocked.AddYöntemi bu amaçla kullanılır.The Interlocked.Add method is used for this purpose.

Aşağıdaki örnek, sınıfının birleştirilmiş kullanımını Monitor ( lock veya dil yapısıyla uygulanan SyncLock ), Interlocked sınıfı ve AutoResetEvent sınıfını gösterir.The following example demonstrates the combined use of the Monitor class (implemented with the lock or SyncLock language construct), the Interlocked class, and the AutoResetEvent class. İki internal (C# ' de) veya Friend (Visual Basic) sınıflarında tanımlar SyncResource ve UnSyncResource bir kaynağa eşitlenmiş ve eşitlenmemiş erişim sağlar.It defines two internal (in C#) or Friend (in Visual Basic) classes, SyncResource and UnSyncResource, that respectively provide synchronized and unsynchronized access to a resource. Örneğin, eşitlenen ve eşitlenmemiş erişim arasındaki farkı (her yöntem çağrısı hızla tamamlanıyorsa durum olabilir) görmek için, yöntemi rastgele bir gecikme içerir: özelliği eşit olan iş parçacıkları için Thread.ManagedThreadId , yöntemi Thread.Sleep 2.000 milisaniyelik bir gecikme sağlamak için çağrılır.To ensure that the example illustrates the difference between the synchronized and unsynchronized access (which could be the case if each method call completes rapidly), the method includes a random delay: for threads whose Thread.ManagedThreadId property is even, the method calls Thread.Sleep to introduce a delay of 2,000 milliseconds. SyncResourceSınıf genel olmadığından, istemci kodundan hiçbiri eşitlenmiş kaynakta kilit almadığından, iç sınıfın kendisi kilidi alır.Note that, because the SyncResource class is not public, none of the client code takes a lock on the synchronized resource; the internal class itself takes the lock. Bu, kötü amaçlı kodun ortak bir nesne üzerinde kilit almasını engeller.This prevents malicious code from taking a lock on a public object.

using System;
using System.Threading;

internal class SyncResource
{
    // Use a monitor to enforce synchronization.
    public void Access()
    {
        lock(this) {
            Console.WriteLine("Starting synchronized resource access on thread #{0}",
                              Thread.CurrentThread.ManagedThreadId);
            if (Thread.CurrentThread.ManagedThreadId % 2 == 0)
                Thread.Sleep(2000);

            Thread.Sleep(200);
            Console.WriteLine("Stopping synchronized resource access on thread #{0}",
                              Thread.CurrentThread.ManagedThreadId);
        }
    }
}

internal class UnSyncResource
{
    // Do not enforce synchronization.
    public void Access()
    {
        Console.WriteLine("Starting unsynchronized resource access on Thread #{0}",
                          Thread.CurrentThread.ManagedThreadId);
        if (Thread.CurrentThread.ManagedThreadId % 2 == 0)
            Thread.Sleep(2000);

        Thread.Sleep(200);
        Console.WriteLine("Stopping unsynchronized resource access on thread #{0}",
                          Thread.CurrentThread.ManagedThreadId);
    }
}

public class App
{
    private static int numOps;
    private static AutoResetEvent opsAreDone = new AutoResetEvent(false);
    private static SyncResource SyncRes = new SyncResource();
    private static UnSyncResource UnSyncRes = new UnSyncResource();

   public static void Main()
   {
        // Set the number of synchronized calls.
        numOps = 5;
        for (int ctr = 0; ctr <= 4; ctr++)
            ThreadPool.QueueUserWorkItem(new WaitCallback(SyncUpdateResource));

        // Wait until this WaitHandle is signaled.
        opsAreDone.WaitOne();
        Console.WriteLine("\t\nAll synchronized operations have completed.\n");

        // Reset the count for unsynchronized calls.
        numOps = 5;
        for (int ctr = 0; ctr <= 4; ctr++)
            ThreadPool.QueueUserWorkItem(new WaitCallback(UnSyncUpdateResource));

        // Wait until this WaitHandle is signaled.
        opsAreDone.WaitOne();
        Console.WriteLine("\t\nAll unsynchronized thread operations have completed.\n");
   }

    static void SyncUpdateResource(Object state)
    {
        // Call the internal synchronized method.
        SyncRes.Access();

        // Ensure that only one thread can decrement the counter at a time.
        if (Interlocked.Decrement(ref numOps) == 0)
            // Announce to Main that in fact all thread calls are done.
            opsAreDone.Set();
    }

    static void UnSyncUpdateResource(Object state)
    {
        // Call the unsynchronized method.
        UnSyncRes.Access();

        // Ensure that only one thread can decrement the counter at a time.
        if (Interlocked.Decrement(ref numOps) == 0)
            // Announce to Main that in fact all thread calls are done.
            opsAreDone.Set();
    }
}
// The example displays output like the following:
//    Starting synchronized resource access on thread #6
//    Stopping synchronized resource access on thread #6
//    Starting synchronized resource access on thread #7
//    Stopping synchronized resource access on thread #7
//    Starting synchronized resource access on thread #3
//    Stopping synchronized resource access on thread #3
//    Starting synchronized resource access on thread #4
//    Stopping synchronized resource access on thread #4
//    Starting synchronized resource access on thread #5
//    Stopping synchronized resource access on thread #5
//
//    All synchronized operations have completed.
//
//    Starting unsynchronized resource access on Thread #7
//    Starting unsynchronized resource access on Thread #9
//    Starting unsynchronized resource access on Thread #10
//    Starting unsynchronized resource access on Thread #6
//    Starting unsynchronized resource access on Thread #3
//    Stopping unsynchronized resource access on thread #7
//    Stopping unsynchronized resource access on thread #9
//    Stopping unsynchronized resource access on thread #3
//    Stopping unsynchronized resource access on thread #10
//    Stopping unsynchronized resource access on thread #6
//
//    All unsynchronized thread operations have completed.
Imports System.Threading

Friend Class SyncResource
    ' Use a monitor to enforce synchronization.
    Public Sub Access()
        SyncLock Me
            Console.WriteLine("Starting synchronized resource access on thread #{0}",
                              Thread.CurrentThread.ManagedThreadId)
            If Thread.CurrentThread.ManagedThreadId Mod 2 = 0 Then
                Thread.Sleep(2000)
            End If
            Thread.Sleep(200)
            Console.WriteLine("Stopping synchronized resource access on thread #{0}",
                              Thread.CurrentThread.ManagedThreadId)
        End SyncLock
    End Sub
End Class

Friend Class UnSyncResource
    ' Do not enforce synchronization.
    Public Sub Access()
        Console.WriteLine("Starting unsynchronized resource access on Thread #{0}",
                          Thread.CurrentThread.ManagedThreadId)
        If Thread.CurrentThread.ManagedThreadId Mod 2 = 0 Then
            Thread.Sleep(2000)
        End If
        Thread.Sleep(200)
        Console.WriteLine("Stopping unsynchronized resource access on thread #{0}",
                          Thread.CurrentThread.ManagedThreadId)
    End Sub
End Class

Public Module App
    Private numOps As Integer
    Private opsAreDone As New AutoResetEvent(False)
    Private SyncRes As New SyncResource()
    Private UnSyncRes As New UnSyncResource()

    Public Sub Main()
        ' Set the number of synchronized calls.
        numOps = 5
        For ctr As Integer = 0 To 4
            ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf SyncUpdateResource))
        Next
        ' Wait until this WaitHandle is signaled.
        opsAreDone.WaitOne()
        Console.WriteLine(vbTab + Environment.NewLine + "All synchronized operations have completed.")
        Console.WriteLine()

        numOps = 5
        ' Reset the count for unsynchronized calls.
        For ctr As Integer = 0 To 4
            ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf UnSyncUpdateResource))
        Next

        ' Wait until this WaitHandle is signaled.
        opsAreDone.WaitOne()
        Console.WriteLine(vbTab + Environment.NewLine + "All unsynchronized thread operations have completed.")
    End Sub

    Sub SyncUpdateResource()
        ' Call the internal synchronized method.
        SyncRes.Access()

        ' Ensure that only one thread can decrement the counter at a time.
        If Interlocked.Decrement(numOps) = 0 Then
            ' Announce to Main that in fact all thread calls are done.
            opsAreDone.Set()
        End If
    End Sub

    Sub UnSyncUpdateResource()
        ' Call the unsynchronized method.
        UnSyncRes.Access()

        ' Ensure that only one thread can decrement the counter at a time.
        If Interlocked.Decrement(numOps) = 0 Then
            ' Announce to Main that in fact all thread calls are done.
            opsAreDone.Set()
        End If
    End Sub
End Module
' The example displays output like the following:
'    Starting synchronized resource access on thread #6
'    Stopping synchronized resource access on thread #6
'    Starting synchronized resource access on thread #7
'    Stopping synchronized resource access on thread #7
'    Starting synchronized resource access on thread #3
'    Stopping synchronized resource access on thread #3
'    Starting synchronized resource access on thread #4
'    Stopping synchronized resource access on thread #4
'    Starting synchronized resource access on thread #5
'    Stopping synchronized resource access on thread #5
'
'    All synchronized operations have completed.
'
'    Starting unsynchronized resource access on Thread #7
'    Starting unsynchronized resource access on Thread #9
'    Starting unsynchronized resource access on Thread #10
'    Starting unsynchronized resource access on Thread #6
'    Starting unsynchronized resource access on Thread #3
'    Stopping unsynchronized resource access on thread #7
'    Stopping unsynchronized resource access on thread #9
'    Stopping unsynchronized resource access on thread #3
'    Stopping unsynchronized resource access on thread #10
'    Stopping unsynchronized resource access on thread #6
'
'    All unsynchronized thread operations have completed.

Örnek, numOps kaynağa erişmeyi deneyecek iş parçacıklarının sayısını tanımlayan bir değişkenini tanımlar.The example defines a variable, numOps, that defines the number of threads that will attempt to access the resource. Uygulama iş parçacığı, ThreadPool.QueueUserWorkItem(WaitCallback) her birinin beş kez eşitlenmiş ve eşitlenmemiş erişim için yöntemini çağırır.The application thread calls the ThreadPool.QueueUserWorkItem(WaitCallback) method for synchronized and unsynchronized access five times each. ThreadPool.QueueUserWorkItem(WaitCallback)Yöntemi, hiçbir parametre kabul etmeyen ve değer döndüren bir temsilci olan tek bir parametreye sahiptir.The ThreadPool.QueueUserWorkItem(WaitCallback) method has a single parameter, a delegate that accepts no parameters and returns no value. Eşitlenmiş erişim için SyncUpdateResource yöntemini çağırır; eşitlenmemiş erişim için UnSyncUpdateResource yöntemini çağırır.For synchronized access, it invokes the SyncUpdateResource method; for unsynchronized access, it invokes the UnSyncUpdateResource method. Her yöntem çağrısı yapıldıktan sonra, uygulama iş parçacığı, örnek sinyallene kadar engellemesini sağlamak için, oto ResetEvent. WaitOne metodunu çağırır AutoResetEvent .After each set of method calls, the application thread calls the AutoResetEvent.WaitOne method so that it blocks until the AutoResetEvent instance is signaled.

Yöntemine yapılan her çağrı SyncUpdateResourceSyncResource.Access yöntemi çağırır ve sonra Interlocked.Decrement sayacı azaltmak için yöntemini çağırır numOps .Each call to the SyncUpdateResource method calls the internal SyncResource.Access method and then calls the Interlocked.Decrement method to decrement the numOps counter. Interlocked.DecrementYöntemi, sayacı azaltmak için kullanılır, aksi takdirde ikinci bir iş parçacığının azaldığı değerin değişkende depolanmadan önce ikinci bir iş parçacığının değere erişeceğinden emin olabilirsiniz.The Interlocked.Decrement method Is used to decrement the counter, because otherwise you cannot be certain that a second thread will access the value before a first thread's decremented value has been stored in the variable. Son eşitlenen çalışan iş parçacığı sayacı sıfıra, eşitlenen tüm iş parçacıklarının kaynağa erişimi tamamladığını belirten şekilde azaltır, SyncUpdateResource yöntemi, EventWaitHandle.Set uygulamaya devam etmek için ana iş parçacığına işaret eden yöntemini çağırır.When the last synchronized worker thread decrements the counter to zero, indicating that all synchronized threads have completed accessing the resource, the SyncUpdateResource method calls the EventWaitHandle.Set method, which signals the main thread to continue execution.

Yöntemine yapılan her çağrı UnSyncUpdateResourceUnSyncResource.Access yöntemi çağırır ve sonra Interlocked.Decrement sayacı azaltmak için yöntemini çağırır numOps .Each call to the UnSyncUpdateResource method calls the internal UnSyncResource.Access method and then calls the Interlocked.Decrement method to decrement the numOps counter. Bir kez daha, Interlocked.Decrement yöntemi, ikinci bir iş parçacığının değere atanmadan önce değere erişememesini sağlamak üzere sayacı azaltmak için kullanılır.Once again, the Interlocked.Decrement method Is used to decrement the counter to ensure that a second thread does not access the value before a first thread's decremented value has been assigned to the variable. Son eşitlenmemiş çalışan iş parçacığı sayacı sıfır olarak azaltır; bu, kaynağa erişmek için daha fazla eşitlenmemiş iş parçacığı olmadığını belirtir, UnSyncUpdateResource yöntemi, EventWaitHandle.Set ana iş parçacığını yürütmeye devam etmek için bildiren yöntemini çağırır.When the last unsynchronized worker thread decrements the counter to zero, indicating that no more unsynchronized threads need to access the resource, the UnSyncUpdateResource method calls the EventWaitHandle.Set method, which signals the main thread to continue execution.

Örneğin çıkışının gösterdiği gibi, eşitlenen erişim, çağıran iş parçacığının başka bir iş parçacığının erişebilmesi için korunan kaynaktan çıkmasını sağlar; her iş parçacığı öncülü bekler.As the output from the example shows, synchronized access ensures that the calling thread exits the protected resource before another thread can access it; each thread waits on its predecessor. Öte yandan, kilit olmadan, UnSyncResource.Access yöntemi iş parçacıklarının kendisine ulaşma sırasına göre çağırılır.On the other hand, without the lock, the UnSyncResource.Access method is called in the order in which threads reach it.

Açıklamalar

MonitorSınıfı Monitor.Enter ,, Monitor.TryEnter ve yöntemlerini çağırarak belirli bir nesne üzerinde bir kilit ayırarak ve serbest bırakarak bir kod bölgesine erişimi eşitlemenize olanak tanır Monitor.Exit .The Monitor class allows you to synchronize access to a region of code by taking and releasing a lock on a particular object by calling the Monitor.Enter, Monitor.TryEnter, and Monitor.Exit methods. Nesne kilitleri, genellikle kritik bir bölüm olarak adlandırılan bir kod bloğuna erişimi kısıtlama yeteneği sağlar.Object locks provide the ability to restrict access to a block of code, commonly called a critical section. Bir iş parçacığı bir nesne için kiline sahip olsa da, başka bir iş parçacığı bu kilidi alamaz.While a thread owns the lock for an object, no other thread can acquire that lock. MonitorDiğer iş parçacığı, farklı bir kilitli nesne kullanarak kodu yürütülemediği müddetçe, başka bir iş parçacığının kilit sahibi tarafından yürütülen uygulama kodunun bir bölümüne erişmesine izin verildiğinden emin olmak için sınıfını da kullanabilirsiniz.You can also use the Monitor class to ensure that no other thread is allowed to access a section of application code being executed by the lock owner, unless the other thread is executing the code using a different locked object.

Bu makalede:In this article:

Monitor sınıfı: genel bakış The Monitor class: An overview
Kilit nesnesi The lock object
Kritik bölüm The critical section
Darbe, PulseAll ve bekleme Pulse, PulseAll, and Wait
İzleyiciler ve bekleme tutamaçlarıMonitors and wait handles

Monitor sınıfı: genel bakışThe Monitor class: An overview

Monitor aşağıdaki özelliklere sahiptir:Monitor has the following features:

  • İstek üzerine bir nesne ile ilişkilendirilir.It is associated with an object on demand.

  • Bağlantısı kesildi, bu, doğrudan herhangi bir bağlamdan çağrılabilecek anlamına gelir.It is unbound, which means it can be called directly from any context.

  • Sınıfın bir örneği oluşturulamıyor Monitor ; Monitor sınıfın yöntemleri tamamen statiktir.An instance of the Monitor class cannot be created; the methods of the Monitor class are all static. Her yönteme, kritik bölüme erişimi denetleyen eşitlenmiş nesne geçirilir.Each method is passed the synchronized object that controls access to the critical section.

Not

Sınıfını, Monitor dizeler dışındaki nesneleri (yani, dışındaki başvuru türleri String ), değer türlerini değil kilitlemek için kullanın.Use the Monitor class to lock objects other than strings (that is, reference types other than String), not value types. Ayrıntılar için Enter Bu makalenin ilerleyen kısımlarında yönteminin ve kilit nesnesinin aşırı yüklemeleri bölümüne bakın.For details, see the overloads of the Enter method and The lock object section later in this article.

Aşağıdaki tabloda, eşitlenen nesnelere erişen iş parçacıkları tarafından alınabilecek eylemler açıklanmaktadır:The following table describes the actions that can be taken by threads that access synchronized objects:

EylemAction AçıklamaDescription
Enter, TryEnterEnter, TryEnter Bir nesne için kilit alır.Acquires a lock for an object. Bu eylem Ayrıca kritik bir bölümün başlangıcını de işaretler.This action also marks the beginning of a critical section. Farklı bir kilitli nesne kullanarak kritik bölümdeki yönergeleri yürütüp, başka bir iş parçacığı önemli bölümü girebilmemiştir.No other thread can enter the critical section unless it is executing the instructions in the critical section using a different locked object.
Wait Diğer iş parçacıklarının nesneye kilitlemesine ve bunlara erişmesine izin vermek için bir nesne üzerindeki kilidi serbest bırakır.Releases the lock on an object in order to permit other threads to lock and access the object. Çağıran iş parçacığı, başka bir iş parçacığının nesneye eriştiği sırada bekler.The calling thread waits while another thread accesses the object. Darbe sinyalleri, bir nesnenin durumundaki değişiklikler hakkında bekleyen iş parçacıklarını bildirmek için kullanılır.Pulse signals are used to notify waiting threads about changes to an object's state.
Pulse (sinyal), PulseAllPulse (signal), PulseAll Bir veya daha fazla bekleyen iş parçacığına bir sinyal gönderir.Sends a signal to one or more waiting threads. Sinyal, kilitli nesnenin durumunun değiştiğini bekleyen bir iş parçacığına bildirir ve kilidin sahibi kilidi serbest bırakmaya hazırlanmıştır.The signal notifies a waiting thread that the state of the locked object has changed, and the owner of the lock is ready to release the lock. Bekleyen iş parçacığı nesnenin için bir kilit alacak şekilde nesnenin Ready kuyruğuna yerleştirilir.The waiting thread is placed in the object's ready queue so that it might eventually receive the lock for the object. İş parçacığında kilit varsa, gerekli duruma ulaşılmadığını görmek için nesnenin yeni durumunu denetleyebilir.Once the thread has the lock, it can check the new state of the object to see if the required state has been reached.
Exit Bir nesne üzerindeki kilidi serbest bırakır.Releases the lock on an object. Bu eylem ayrıca kilitli nesne tarafından korunan kritik bir bölümün sonunu de işaretler.This action also marks the end of a critical section protected by the locked object.

İle başlayarak, .NET Framework 4.NET Framework 4 ve yöntemleri için iki aşırı yükleme kümesi vardır Enter TryEnter .Beginning with the .NET Framework 4.NET Framework 4, there are two sets of overloads for the Enter and TryEnter methods. Tek bir aşırı yükleme kümesi, kilit ref ByRef alınırken bir Boolean true özel durum oluşsa bile, kilit alınırsa, bir istisna elde edildiğinde, bir (C# ' de) veya (Visual Basic) parametresinde oluşur.One set of overloads has a ref (in C#) or ByRef (in Visual Basic) Boolean parameter that is atomically set to true if the lock is acquired, even if an exception is thrown when acquiring the lock. Kilidin koruduğu kaynaklar tutarlı bir durumda olmasa bile, her durumda kilidi serbest bırakmak kritik ise bu aşırı yüklemeleri kullanın.Use these overloads if it is critical to release the lock in all cases, even when the resources the lock is protecting might not be in a consistent state.

Kilit nesnesiThe lock object

Monitor sınıfı, static Shared kritik bölüme erişimi denetleyen bir nesne üzerinde çalışan (C# ' de) veya (Visual Basic) yöntemlerinde oluşur.The Monitor class consists of static (in C#) or Shared (in Visual Basic) methods that operate on an object that controls access to the critical section. Eşitlenmiş her nesne için aşağıdaki bilgiler korunur:The following information is maintained for each synchronized object:

  • Şu anda kilidi tutan iş parçacığına başvuru.A reference to the thread that currently holds the lock.

  • Kilidi almaya hazırlanma iş parçacıklarını içeren, Ready kuyruğuna başvuru.A reference to a ready queue, which contains the threads that are ready to obtain the lock.

  • Kilitli nesnenin durumundaki bir değişikliğin bildirimini bekleyen iş parçacıklarını içeren bir bekleme kuyruğuna başvuru.A reference to a waiting queue, which contains the threads that are waiting for notification of a change in the state of the locked object.

Monitor nesneleri (yani, başvuru türleri), değer türlerini değil kilitler.Monitor locks objects (that is, reference types), not value types. Ve ' a bir değer türü geçirebilmeniz Enter Exit mümkün olsa da, her çağrı için ayrı olarak paketlenmelidir.While you can pass a value type to Enter and Exit, it is boxed separately for each call. Her çağrı ayrı bir nesne oluşturduğundan, Enter hiçbir zaman engellenemeyen ve kodun düzgün şekilde korunmasından dolayı gerçekten eşitlenmez.Since each call creates a separate object, Enter never blocks, and the code it is supposedly protecting is not really synchronized. Ayrıca, geçirilen nesne Exit öğesine geçirilen nesneden farklı olduğundan Enter , Monitor SynchronizationLockException "nesne eşitleme yöntemi zaman uyumsuz bir kod bloğundan çağrıldı" iletisiyle özel durum oluşturur.In addition, the object passed to Exit is different from the object passed to Enter, so Monitor throws SynchronizationLockException exception with the message "Object synchronization method was called from an unsynchronized block of code."

Aşağıdaki örnekte bu sorun gösterilmektedir.The following example illustrates this problem. Her biri 250 milisaniye boyunca yalnızca uyku moduna geçen on görevi başlatır.It launches ten tasks, each of which just sleeps for 250 milliseconds. Ardından her görev, nTasks gerçekten başlatılmış ve yürütülen görev sayısını saymak amaçlanan bir sayaç değişkenini günceller.Each task then updates a counter variable, nTasks, which is intended to count the number of tasks that actually launched and executed. nTasksBirden çok görev tarafından aynı anda güncelleştirilebildiği genel bir değişken olduğundan, birden çok görev tarafından eşzamanlı değişiklik yapılmasını korumak için bir izleyici kullanılır.Because nTasks is a global variable that can be updated by multiple tasks simultaneously, a monitor is used to protect it from simultaneous modification by multiple tasks. Ancak, örneğin çıktısında gösterildiği gibi, görevlerin her biri bir SynchronizationLockException özel durum oluşturur.However, as the output from the example shows, each of the tasks throws a SynchronizationLockException exception.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {

      int nTasks = 0;
      List<Task> tasks = new List<Task>();

      try {
         for (int ctr = 0; ctr < 10; ctr++)
            tasks.Add(Task.Run( () => { // Instead of doing some work, just sleep.
                                        Thread.Sleep(250);
                                        // Increment the number of tasks.
                                        Monitor.Enter(nTasks);
                                        try {
                                           nTasks += 1;
                                        }
                                        finally {
                                           Monitor.Exit(nTasks);
                                        }
                                      } ));
         Task.WaitAll(tasks.ToArray());
         Console.WriteLine("{0} tasks started and executed.", nTasks);
      }
      catch (AggregateException e) {
         String msg = String.Empty;
         foreach (var ie in e.InnerExceptions) {
            Console.WriteLine("{0}", ie.GetType().Name);
            if (! msg.Contains(ie.Message))
               msg += ie.Message + Environment.NewLine;
         }
         Console.WriteLine("\nException Message(s):");
         Console.WriteLine(msg);
      }
   }
}
// The example displays the following output:
//    SynchronizationLockException
//    SynchronizationLockException
//    SynchronizationLockException
//    SynchronizationLockException
//    SynchronizationLockException
//    SynchronizationLockException
//    SynchronizationLockException
//    SynchronizationLockException
//    SynchronizationLockException
//    SynchronizationLockException
//
//    Exception Message(s):
//    Object synchronization method was called from an unsynchronized block of code.
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim nTasks As Integer = 0
      Dim tasks As New List(Of Task)()

      Try
         For ctr As Integer = 0 To 9
            tasks.Add(Task.Run( Sub()
                                   ' Instead of doing some work, just sleep.
                                   Thread.Sleep(250)
                                   ' Increment the number of tasks.
                                   Monitor.Enter(nTasks)
                                   Try
                                      nTasks += 1
                                   Finally
                                      Monitor.Exit(nTasks)
                                   End Try
                                End Sub))
         Next
         Task.WaitAll(tasks.ToArray())
         Console.WriteLine("{0} tasks started and executed.", nTasks)
      Catch e As AggregateException
         Dim msg AS String = String.Empty
         For Each ie In e.InnerExceptions
            Console.WriteLine("{0}", ie.GetType().Name)
            If Not msg.Contains(ie.Message) Then
               msg += ie.Message + Environment.NewLine
            End If
         Next
         Console.WriteLine(vbCrLf + "Exception Message(s):")
         Console.WriteLine(msg)
      End Try
   End Sub
End Module
' The example displays the following output:
'    SynchronizationLockException
'    SynchronizationLockException
'    SynchronizationLockException
'    SynchronizationLockException
'    SynchronizationLockException
'    SynchronizationLockException
'    SynchronizationLockException
'    SynchronizationLockException
'    SynchronizationLockException
'    SynchronizationLockException
'
'    Exception Message(s):
'    Object synchronization method was called from an unsynchronized block of code.

Her görev bir SynchronizationLockException özel durum oluşturur çünkü nTasks değişken her görevde yönteme çağrıdan önce paketlenmelidir Monitor.Enter .Each task throws a SynchronizationLockException exception because the nTasks variable is boxed before the call to the Monitor.Enter method in each task. Diğer bir deyişle, her yöntem çağrısı diğerlerinden bağımsız olan ayrı bir değişkene geçirilir.In other words, each method call is passed a separate variable that is independent of the others. nTasks yöntemine yapılan çağrıda bir kez daha yer verilir Monitor.Exit .nTasks is boxed again in the call to the Monitor.Exit method. Bu, bir kez daha, nTasks ve yöntemi çağrısında oluşturulan on kutulanmış değişkenden bağımsız olan on yeni paketlenmiş değişken oluşturur Monitor.Enter .Once again, this creates ten new boxed variables, which are independent of each other, nTasks, and the ten boxed variables created in the call to the Monitor.Enter method. Kod, daha önce kilitli olmayan yeni oluşturulan bir değişkende bir kilit bırakmaya çalıştığından, bu durum oluşturulur.The exception is thrown, then, because our code is attempting to release a lock on a newly created variable that was not previously locked.

, Ve ' yi çağırmadan önce bir değer türü değişkeni Enter ve Exit Aşağıdaki örnekte gösterildiği gibi, aynı paketlenmiş nesneyi her iki yönteme de geçirirseniz, bunu yapmanın bir avantajı yoktur.Although you can box a value type variable before calling Enter and Exit, as shown in the following example, and pass the same boxed object to both methods, there is no advantage to doing this. Kutulanmamış değişkende yapılan değişiklikler kutulanmış kopyada yansıtılmaz ve paketlenmiş kopyanın değerini değiştirme yolu yoktur.Changes to the unboxed variable are not reflected in the boxed copy, and there is no way to change the value of the boxed copy.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {

      int nTasks = 0;
      object o = nTasks;
      List<Task> tasks = new List<Task>();

      try {
         for (int ctr = 0; ctr < 10; ctr++)
            tasks.Add(Task.Run( () => { // Instead of doing some work, just sleep.
                                        Thread.Sleep(250);
                                        // Increment the number of tasks.
                                        Monitor.Enter(o);
                                        try {
                                           nTasks++;
                                        }
                                        finally {
                                           Monitor.Exit(o);
                                        }
                                      } ));
         Task.WaitAll(tasks.ToArray());
         Console.WriteLine("{0} tasks started and executed.", nTasks);
      }
      catch (AggregateException e) {
         String msg = String.Empty;
         foreach (var ie in e.InnerExceptions) {
            Console.WriteLine("{0}", ie.GetType().Name);
            if (! msg.Contains(ie.Message))
               msg += ie.Message + Environment.NewLine;
         }
         Console.WriteLine("\nException Message(s):");
         Console.WriteLine(msg);
      }
   }
}
// The example displays the following output:
//        10 tasks started and executed.
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim nTasks As Integer = 0
      Dim o As Object = nTasks
      Dim tasks As New List(Of Task)()

      Try
         For ctr As Integer = 0 To 9
            tasks.Add(Task.Run( Sub()
                                   ' Instead of doing some work, just sleep.
                                   Thread.Sleep(250)
                                   ' Increment the number of tasks.
                                   Monitor.Enter(o)
                                   Try
                                      nTasks += 1
                                   Finally
                                      Monitor.Exit(o)
                                   End Try
                                End Sub))
         Next
         Task.WaitAll(tasks.ToArray())
         Console.WriteLine("{0} tasks started and executed.", nTasks)
      Catch e As AggregateException
         Dim msg AS String = String.Empty
         For Each ie In e.InnerExceptions
            Console.WriteLine("{0}", ie.GetType().Name)
            If Not msg.Contains(ie.Message) Then
               msg += ie.Message + Environment.NewLine
            End If
         Next
         Console.WriteLine(vbCrLf + "Exception Message(s):")
         Console.WriteLine(msg)
      End Try
   End Sub
End Module
' The example displays the following output:
'       10 tasks started and executed.

Üzerinde eşitlenmesi gereken bir nesne seçerken, yalnızca özel veya iç nesnelerde kilitleme yapmanız gerekir.When selecting an object on which to synchronize, you should lock only on private or internal objects. İlişkisiz kod farklı amaçlar için kilitlemek üzere aynı nesneleri seçebildiğinden, dış nesnelerde kilitleme kilitlenme neden olabilir.Locking on external objects might result in deadlocks, because unrelated code could choose the same objects to lock on for different purposes.

Kilit için kullanılan nesnenin Öğesinden türemesi durumunda birden çok uygulama etki alanındaki bir nesne üzerinde eşitlenebileceğinizi unutmayın MarshalByRefObject .Note that you can synchronize on an object in multiple application domains if the object used for the lock derives from MarshalByRefObject.

Kritik bölümThe critical section

Enter Exit Kritik bir bölümün başlangıcını ve sonunu işaretlemek için ve yöntemlerini kullanın.Use the Enter and Exit methods to mark the beginning and end of a critical section.

Not

Ve yöntemleri tarafından sunulan işlevsellik Enter , Exit C# ' deki lock Ifadesiyle ve Visual Basic içindeki SyncLock ifadesiyle aynı şekilde, dil yapıları Monitor.Enter(Object, Boolean) yöntem aşırı yüklemesini ve Monitor.Exit yöntemini bir try ...finallyThe functionality provided by the Enter and Exit methods is identical to that provided by the lock statement in C# and the SyncLock statement in Visual Basic, except that the language constructs wrap the Monitor.Enter(Object, Boolean) method overload and the Monitor.Exit method in a tryfinally blok yayınlantığınızdan emin olmak için engelleyin.block to ensure that the monitor is released.

Kritik bölüm bir ardışık yönergeler kümesi ise, yöntemi tarafından alınan kilit, Enter yalnızca tek bir iş parçacığının kilitli nesne ile iliştirilmiş kodu yürütebilmesi güvence altına alır.If the critical section is a set of contiguous instructions, then the lock acquired by the Enter method guarantees that only a single thread can execute the enclosed code with the locked object. Bu durumda, bu kodu bir try blokta yerleştirmenizi ve çağrıyı Exit bir blokta yerleştirmenizi öneririz finally .In this case, we recommend that you place that code in a try block and place the call to the Exit method in a finally block. Bu, bir özel durum oluşması durumunda kilidi serbest bırakmasını sağlar.This ensures that the lock is released even if an exception occurs. Aşağıdaki kod parçası bu kalıbı gösterir.The following code fragment illustrates this pattern.

// Define the lock object.
var obj = new Object();

// Define the critical section.
Monitor.Enter(obj);
try {
   // Code to execute one thread at a time.
}
// catch blocks go here.
finally {
   Monitor.Exit(obj);
}
' Define the lock object.
Dim obj As New Object()

' Define the critical section.
Monitor.Enter(obj)
Try 
   ' Code to execute one thread at a time.

' catch blocks go here.
Finally 
   Monitor.Exit(obj)
End Try

Bu özellik genellikle, bir sınıfın statik veya örnek metoduna erişimi eşleştirmek için kullanılır.This facility is typically used to synchronize access to a static or instance method of a class.

Kritik bir bölüm bir yöntemin tamamına yayılırsa, System.Runtime.CompilerServices.MethodImplAttribute metodu yöntemine yerleştirerek ve içindeki değeri belirterek kilitleme özelliği elde edilebilir Synchronized System.Runtime.CompilerServices.MethodImplAttribute .If a critical section spans an entire method, the locking facility can be achieved by placing the System.Runtime.CompilerServices.MethodImplAttribute on the method, and specifying the Synchronized value in the constructor of System.Runtime.CompilerServices.MethodImplAttribute. Bu özniteliği kullandığınızda, Enter ve Exit yöntemi çağrıları gerekli değildir.When you use this attribute, the Enter and Exit method calls are not needed. Aşağıdaki kod parçası bu kalıbı göstermektedir:The following code fragment illustrates this pattern:

[MethodImplAttribute(MethodImplOptions.Synchronized)]
void MethodToLock()
{
   // Method implementation.
} 
<MethodImplAttribute(MethodImplOptions.Synchronized)>
Sub MethodToLock()
   ' Method implementation.
End Sub 

Özniteliğin, yöntemin dönüşene kadar geçerli iş parçacığının kilidi tutmasına neden olduğunu unutmayın; kilit daha önce yayımlanacaksa, Monitor özniteliği yerine yöntemi içindeki Class, C# Lock Ifadesini veya Visual Basic SyncLock ifadesini kullanın.Note that the attribute causes the current thread to hold the lock until the method returns; if the lock can be released sooner, use the Monitor class, the C# lock statement, or the Visual Basic SyncLock statement inside of the method instead of the attribute.

Enter Exit Belirli bir nesneyi kilitleyip veya sınıf sınırlarına veya her ikisine de kilitleyen deyimler mümkün olsa da, bu uygulama önerilmez.While it is possible for the Enter and Exit statements that lock and release a given object to cross member or class boundaries or both, this practice is not recommended.

Darbe, PulseAll ve beklemePulse, PulseAll, and Wait

Bir iş parçacığı kilidin sahibi olduktan ve kilidin koruduğu kritik bölümü girdikten sonra,, Monitor.Wait Monitor.Pulse ve Monitor.PulseAll yöntemlerini çağırabilir.Once a thread owns the lock and has entered the critical section that the lock protects, it can call the Monitor.Wait, Monitor.Pulse, and Monitor.PulseAll methods.

Kilitleme çağrılarını tutan iş parçacığı Wait , kilit serbest bırakılır ve iş parçacığı eşitlenmiş nesnenin bekleme kuyruğuna eklenir.When the thread that holds the lock calls Wait, the lock is released and the thread is added to the waiting queue of the synchronized object. Hazırlama sırasındaki ilk iş parçacığı, varsa kilidi alır ve kritik bölümüne girer.The first thread in the ready queue, if any, acquires the lock and enters the critical section. Çağıran iş parçacığı Wait , Monitor.Pulse ya da Monitor.PulseAll yöntemi kilidi tutan iş parçacığı tarafından çağrıldığında, bekleme sırasından Ready kuyruğuna taşınır (taşınmak için, iş parçacığının bekleyen kuyruğun başlangıcında olması gerekir).The thread that called Wait is moved from the waiting queue to the ready queue when either the Monitor.Pulse or the Monitor.PulseAll method is called by the thread that holds the lock (to be moved, the thread must be at the head of the waiting queue). WaitYöntemi, çağıran iş parçacığı kilidi yeniden edindiğinde döndürür.The Wait method returns when the calling thread reacquires the lock.

Kilitleme çağrılarını tutan iş parçacığı Pulse , bekleme sırasının başındaki iş parçacığı, Ready kuyruğuna taşınır.When the thread that holds the lock calls Pulse, the thread at the head of the waiting queue is moved to the ready queue. Yöntemine yapılan çağrı, PulseAll bekleme kuyruğundaki tüm iş parçacıklarını Ready kuyruğuna gider.The call to the PulseAll method moves all the threads from the waiting queue to the ready queue.

İzleyiciler ve bekleme tutamaçlarıMonitors and wait handles

Sınıfının ve nesnelerinin kullanımı arasındaki ayrımı dikkate almak önemlidir Monitor WaitHandle .It is important to note the distinction between the use of the Monitor class and WaitHandle objects.

  • MonitorSınıf tamamen yönetilir, tamamen taşınabilir ve işletim sistemi kaynak gereksinimleri açısından daha verimli olabilir.The Monitor class is purely managed, fully portable, and might be more efficient in terms of operating-system resource requirements.

  • WaitHandle nesneler, işletim sistemi ile uyumlu olmayan nesneleri temsil eder, yönetilen ve yönetilmeyen kod arasında eşitleme için faydalıdır ve aynı anda birçok nesneyi bekleme özelliği gibi gelişmiş işletim sistemi özelliklerini kullanıma sunar.WaitHandle objects represent operating-system waitable objects, are useful for synchronizing between managed and unmanaged code, and expose some advanced operating-system features like the ability to wait on many objects at once.

Özellikler

LockContentionCount

İzleyicinin kilidini almaya çalışırken kaç kez çekişme olduğunu alır.Gets the number of times there was contention when trying to take the monitor's lock.

Yöntemler

Enter(Object)

Belirtilen nesne üzerinde dışlamalı bir kilit elde edin.Acquires an exclusive lock on the specified object.

Enter(Object, Boolean)

Belirtilen nesne üzerinde özel bir kilit alır ve kilitlenmesinin yapılıp yapılmayacağını belirten bir değer belirler.Acquires an exclusive lock on the specified object, and atomically sets a value that indicates whether the lock was taken.

Exit(Object)

Belirtilen nesne üzerinde dışlamalı bir kilit yayınlar.Releases an exclusive lock on the specified object.

IsEntered(Object)

Geçerli iş parçacığının belirtilen nesne üzerindeki kilidi içerip içermediğini belirler.Determines whether the current thread holds the lock on the specified object.

Pulse(Object)

Kilitli nesnenin durumundaki bir değişikliğin bekleme kuyruğunda bir iş parçacığına bildirir.Notifies a thread in the waiting queue of a change in the locked object's state.

PulseAll(Object)

Nesnenin durumundaki bir değişikliğin tüm bekleyen iş parçacıklarını bilgilendirir.Notifies all waiting threads of a change in the object's state.

TryEnter(Object)

Belirtilen nesne üzerinde özel bir kilit elde etme girişiminde bulunur.Attempts to acquire an exclusive lock on the specified object.

TryEnter(Object, Boolean)

Belirtilen nesne üzerinde özel bir kilit elde etmeye çalışır ve kilidin yapılıp yapılmadığını belirten bir değer belirler.Attempts to acquire an exclusive lock on the specified object, and atomically sets a value that indicates whether the lock was taken.

TryEnter(Object, Int32)

Belirtilen nesne üzerinde özel bir kilit almak için belirtilen milisaniye sayısı için denemeler.Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object.

TryEnter(Object, Int32, Boolean)

Belirtilen nesne üzerinde özel bir kilit elde etmek için belirtilen milisaniye sayısı için denemeler yapar ve kilitlenmesinin yapılıp yapılmayacağını belirten bir değer belirler.Attempts, for the specified number of milliseconds, to acquire an exclusive lock on the specified object, and atomically sets a value that indicates whether the lock was taken.

TryEnter(Object, TimeSpan)

Belirtilen nesne üzerinde özel bir kilit almak için belirtilen süre için denemeler.Attempts, for the specified amount of time, to acquire an exclusive lock on the specified object.

TryEnter(Object, TimeSpan, Boolean)

Belirtilen nesne üzerinde özel bir kilit elde etmek için, belirtilen süre boyunca denemeler yapar ve kilidin yapılıp yapılmayacağını belirten bir değeri kaldırıldı olarak belirler.Attempts, for the specified amount of time, to acquire an exclusive lock on the specified object, and atomically sets a value that indicates whether the lock was taken.

Wait(Object)

Bir nesne üzerinde kilidi serbest bırakır ve kilidi yeniden edinene kadar geçerli iş parçacığını engeller.Releases the lock on an object and blocks the current thread until it reacquires the lock.

Wait(Object, Int32)

Bir nesne üzerinde kilidi serbest bırakır ve kilidi yeniden edinene kadar geçerli iş parçacığını engeller.Releases the lock on an object and blocks the current thread until it reacquires the lock. Belirtilen zaman aşımı aralığı geçtiğinde, iş parçacığı hazır kuyruğuna girer.If the specified time-out interval elapses, the thread enters the ready queue.

Wait(Object, Int32, Boolean)

Bir nesne üzerinde kilidi serbest bırakır ve kilidi yeniden edinene kadar geçerli iş parçacığını engeller.Releases the lock on an object and blocks the current thread until it reacquires the lock. Belirtilen zaman aşımı aralığı geçtiğinde, iş parçacığı hazır kuyruğuna girer.If the specified time-out interval elapses, the thread enters the ready queue. Bu yöntem ayrıca, bağlam için eşitleme etki alanının (eşitlenen bir bağlamda), bekleme ve yeniden alınmadan önce çıkılmadığını belirtir.This method also specifies whether the synchronization domain for the context (if in a synchronized context) is exited before the wait and reacquired afterward.

Wait(Object, TimeSpan)

Bir nesne üzerinde kilidi serbest bırakır ve kilidi yeniden edinene kadar geçerli iş parçacığını engeller.Releases the lock on an object and blocks the current thread until it reacquires the lock. Belirtilen zaman aşımı aralığı geçtiğinde, iş parçacığı hazır kuyruğuna girer.If the specified time-out interval elapses, the thread enters the ready queue.

Wait(Object, TimeSpan, Boolean)

Bir nesne üzerinde kilidi serbest bırakır ve kilidi yeniden edinene kadar geçerli iş parçacığını engeller.Releases the lock on an object and blocks the current thread until it reacquires the lock. Belirtilen zaman aşımı aralığı geçtiğinde, iş parçacığı hazır kuyruğuna girer.If the specified time-out interval elapses, the thread enters the ready queue. İsteğe bağlı olarak, eşitlemeden önce eşitlenmiş bağlam için eşitleme etki alanından çıkıp etki alanını daha sonra yeniden elde edin.Optionally exits the synchronization domain for the synchronized context before the wait and reacquires the domain afterward.

Şunlara uygulanır

İş Parçacığı Güvenliği

Bu güvenli iş parçacığı türüdür.This type is thread safe.

Ayrıca bkz.