مشاركة عبر


أجهزة العرض

Monitorالكائنات كشف القدرة تشغيل يزامن الوصول إلى منطقة من تعليمات برمجية بتنفيذه وتحرير قفل تشغيل كائن معين باستخدامجهاز العرض.Enter الزرو جهاز العرض.TryEnter جهاز العرض.خروج وظائف. بعد الحصول تشغيل قفل منطقة التعليمات برمجية، يمكنك استخدام جهاز العرض.Wait ، جهاز العرض.Pulse ، و أساليب جهاز العرض.PulseAll . الانتظار بتحرير التأمين إذا يتم تعليق، وينتظر أن يتم إعلامك. عند انتظار هو إعلام، ترجع ويحصل على التأمين مرة أخرى. إشارة PulseAll من لمؤشر الترابط التالي في قائمة انتظار "الانتظار و ذبذبة إلى المتابعة.

Visual أساسى SyncLockو C# lockاستخدام عبارات Monitor.Enterإلى الحصول على التأمين و Monitor.Exitإلى لإصدار it. الفائدة التي تنتج عن استخدام عبارات لغة في هو هذا كل شيء في lockأو SyncLockحظر هو مضمنة في Tryالعبارة. Tryله عبارة Finallyحظر لضمان أن التأمين هو إصدارها.

جهاز العرض بتأمين الكائنات (التي هو، الإشارة إلى أنواع)، غير القيمة أنواع. بينما يمكنك تمرير نوع القيمة إلى Enter الزر الزر و إنهاء، في ذلك هو مربع شكل منفصل لكل اتصال. وبما أن ينشئ كل استدعاء كائن منفصل و أدخل لا كتل التعليمات البرمجية هو supposedly حماية هو مزامنة ليس صحيحاً. بالإضافة إلى تمرير الكائن إلى إنهاء هو مختلفة عن الكائن الذي تم تمريره إلى الإدخال، لذا مراقبة يطرح SynchronizationLockExceptionمع الرسالة "كائن تم استدعاء أسلوب تزامن من حظر غير متزامنة من تعليمات برمجية." يلي مثال يوضح هذه المشاكل.

Private x As Integer
' The next line creates a generic object containing the value of 
' x each time the code is executed, so that Enter never blocks.
Monitor.Enter(x)
Try
    ' Code that needs to be protected by the monitor.
Finally
    ' Always use Finally to ensure that you exit the Monitor.
    ' The following line creates another object containing 
    ' the value of x, and throws SynchronizationLockException
    ' because the two objects do not match.
    Monitor.Exit(x)
End Try
private int x;
// The next line creates a generic object containing the value of
// x each time the code is executed, so that Enter never blocks.
Monitor.Enter(x);
try {
    // Code that needs to be protected by the monitor.
}
finally {
    // Always use Finally to ensure that you exit the Monitor.
    // The following line creates another object containing 
    // the value of x, and throws SynchronizationLockException
    // because the two objects do not match.
    Monitor.Exit(x);
}

وعلى الرغم من أنه يمكنك صندوق متغير نوع القيمة قبل استدعاء Enter الزر الزر و إنهاء ، كما هو موضح في المثال التالي، وتمرير نفس الكائن في صندوق إلى كلا الأسلوبين، هناك مزايا لا إلى القيام بذلك. لا تنعكس التغييرات إلى المتغير في النسخة في مربع، وهناك هو لا توجد طريقة لتغيير القيمة في مربع النسخة.

Private o As Object = x
private Object o = x;

هو الهام ملاحظة dهوtinction بين استخدام مراقبة وكائنات WaitHandle . جهاز العرضتكون الكائنات إلى مدارة، تماما المحمولة و قد يكون أكثر فعالية من متطلبات موارد النظام التشغيل. WaitHandle كائنات تمثل الكائنات waitable لالنظام التشغيل، مفيدة بين تزامن المدارة وغير مدارة تعليمات برمجية، وعرض بعض ميزات النظام التشغيل المتقدمة مثل القدرة تشغيل الانتظار تشغيل كائنات متعددة في نفس الوقت.

يوضح مثال التعليمة البرمجية التالية تضم استخدم من Monitorفئة (تنفيذها مع lockو SyncLockعبارات المترجم)، Interlockedفئة، و AutoResetEventclass.

Imports System
Imports System.Threading
Imports Microsoft.VisualBasic

' Note: The class whose internal public member is the synchronizing method
' is not public; none of the client code takes a lock on the Resource object.
' The member of the nonpublic class takes the lock on itself. Written this 
' way, malicious code cannot take a lock on a public object.
Class SyncResource
   
   Public Sub Access(threadNum As Int32)
      ' Uses Monitor class to enforce synchronization.
      SyncLock Me
         ' Synchronized: Despite the next conditional, each thread 
         ' waits on its predecessor.
         If threadNum Mod 2 = 0 Then
            Thread.Sleep(2000)
         End If
         Console.WriteLine("Start Synched Resource access (Thread={0})", threadNum)
         Thread.Sleep(200)
         Console.WriteLine("Stop Synched Resource access (Thread={0})", threadNum)
      End SyncLock
   End Sub 'Access
End Class 'SyncResource

' Without the lock, the method is called in the order in which 
' threads reach it.
Class UnSyncResource
   
   Public Sub Access(threadNum As Int32)
      ' Does not use Monitor class to enforce synchronization.
      ' The next call throws the thread order.
      If threadNum Mod 2 = 0 Then
         Thread.Sleep(2000)
      End If
      Console.WriteLine("Start UnSynched Resource access (Thread={0})", threadNum)
      Thread.Sleep(200)
      Console.WriteLine("Stop UnSynched Resource access (Thread={0})", threadNum)
   End Sub 'Access
End Class 'UnSyncResource

Public Class App
   Private Shared numAsyncOps As Int32 = 5
   Private Shared asyncOpsAreDone As New AutoResetEvent(False)
   Private Shared SyncRes As New SyncResource()
   Private Shared UnSyncRes As New UnSyncResource()
   Private Shared threadNum As Int32
   Public Shared Sub Main()
      
      For threadNum = 0 To 4
         ThreadPool.QueueUserWorkItem(AddressOf SyncUpdateResource, threadNum)
      Next threadNum
      
      ' Wait until this WaitHandle is signaled.
      asyncOpsAreDone.WaitOne()
      Console.WriteLine(ControlChars.Tab + ControlChars.Lf + "All synchronized operations have completed." + ControlChars.Lf)
      
      ' Reset the thread count for unsynchronized calls.
      numAsyncOps = 5
      
      For threadNum = 0 To 4
         ThreadPool.QueueUserWorkItem(AddressOf UnSyncUpdateResource, threadNum)
      Next threadNum
      
      ' Wait until this WaitHandle is signaled.
      asyncOpsAreDone.WaitOne()
      Console.WriteLine(ControlChars.Tab + ControlChars.Cr + "All unsynchronized thread operations have completed.")
   End Sub 'Main
   
   
   
   ' The callback method's signature MUST match that of 
   ' a System.Threading.TimerCallback delegate
   ' (it takes an Object parameter and returns void).
   Shared Sub SyncUpdateResource(state As Object)
      ' This calls the internal synchronized method, passing 
      ' a thread number.
      SyncRes.Access(CType(state, Int32))
      
      ' Count down the number of methods that the threads have called.
      ' This must be synchronized, however; you cannot know which thread 
      ' will access the value **before** another thread's incremented 
      ' value has been stored into the variable.
      If Interlocked.Decrement(numAsyncOps) = 0 Then
         asyncOpsAreDone.Set() 
         ' Announce to Main that in fact all thread calls are done.
      End If
   End Sub 'SyncUpdateResource
    
   ' The callback method's signature MUST match that of 
   ' a System.Threading.TimerCallback delegate
   ' (it takes an Object parameter and returns void).
   Shared Sub UnSyncUpdateResource(state As [Object])
      ' This calls the unsynchronized method, passing 
      ' a thread number.
      UnSyncRes.Access(CType(state, Int32))
      
      ' Count down the number of methods that the threads have called.
      ' This must be synchronized, however; you cannot know which thread 
      ' will access the value **before** another thread's incremented 
      ' value has been stored into the variable.
      If Interlocked.Decrement(numAsyncOps) = 0 Then
         asyncOpsAreDone.Set() 
         ' Announce to Main that in fact all thread calls are done.
      End If
   End Sub 'UnSyncUpdateResource 
End Class 'App
using System;
using System.Threading;

// Note: The class whose internal public member is the synchronizing 
// method is not public; none of the client code takes a lock on the 
// Resource object.The member of the nonpublic class takes the lock on 
// itself. Written this way, malicious code cannot take a lock on 
// a public object.
class SyncResource {
   public void Access(Int32 threadNum) {
      // Uses Monitor class to enforce synchronization.
      lock (this) {
       // Synchronized: Despite the next conditional, each thread 
       // waits on its predecessor.
       if (threadNum % 2 == 0)
         Thread.Sleep(2000);
         Console.WriteLine("Start Synched Resource access (Thread={0})", threadNum);
         Thread.Sleep(200);
         Console.WriteLine("Stop Synched Resource access (Thread={0})", threadNum);
      }
   }
}

// Without the lock, the method is called in the order in which threads reach it.
class UnSyncResource {
   public void Access(Int32 threadNum) {
    // Does not use Monitor class to enforce synchronization.
    // The next call throws the thread order.
    if (threadNum % 2 == 0)
      Thread.Sleep(2000);
     Console.WriteLine("Start UnSynched Resource access (Thread={0})", threadNum);
     Thread.Sleep(200);
     Console.WriteLine("Stop UnSynched Resource access (Thread={0})", threadNum);
   }
}

public class App {
   static Int32 numAsyncOps = 5;
   static AutoResetEvent asyncOpsAreDone = new AutoResetEvent(false);
   static SyncResource SyncRes = new SyncResource();
   static UnSyncResource UnSyncRes = new UnSyncResource();

   public static void Main() {

      for (Int32 threadNum = 0; threadNum < 5; threadNum++) {
         ThreadPool.QueueUserWorkItem(new WaitCallback(SyncUpdateResource), threadNum);
      }

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

     // Reset the thread count for unsynchronized calls.
     numAsyncOps = 5;

      for (Int32 threadNum = 0; threadNum < 5; threadNum++) {
         ThreadPool.QueueUserWorkItem(new WaitCallback(UnSyncUpdateResource), threadNum);
      }

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


   // The callback method's signature MUST match that of a 
   // System.Threading.TimerCallback delegate (it takes an Object 
   // parameter and returns void).
   static void SyncUpdateResource(Object state) {
     // This calls the internal synchronized method, passing 
     // a thread number.
      SyncRes.Access((Int32) state);

     // Count down the number of methods that the threads have called.
     // This must be synchronized, however; you cannot know which thread 
     // will access the value **before** another thread's incremented 
     // value has been stored into the variable.
      if (Interlocked.Decrement(ref numAsyncOps) == 0)
         asyncOpsAreDone.Set(); 
         // Announce to Main that in fact all thread calls are done.
   }

   // The callback method's signature MUST match that of a 
   // System.Threading.TimerCallback delegate (it takes an Object 
   // parameter and returns void).
   static void UnSyncUpdateResource(Object state) {
     // This calls the unsynchronized method, passing a thread number.
      UnSyncRes.Access((Int32) state);

     // Count down the number of methods that the threads have called.
     // This must be synchronized, however; you cannot know which thread 
     // will access the value **before** another thread's incremented 
     // value has been stored into the variable.
      if (Interlocked.Decrement(ref numAsyncOps) == 0)
         asyncOpsAreDone.Set(); 
         // Announce to Main that in fact all thread calls are done.
   }
}

راجع أيضًا:

المرجع

Monitor

موارد أخرى

ترابط الكائنات و الميزات