Timer [C #]
The timer is a lightweight object that allows you to specify a delegate to the specified time call. Threads in the thread pool perform a wait operation.
It is very simple to use the Timer class. A Timer needs to be created (by passing the TimerCallback delegate to the callback method), a time indicating the status of the time to be transferred to the time, and the time period indicating the time period between the callback call. To cancel the pending timer, call the Timer.Dispose function.
Note that there is also the System.Windows.Forms.Timer class. This class is based on the operating system timer support, if you do not send a message on the thread, the timer will not appear. This makes System.Threading.Timer more useful in many cases.
The following simple code example illustrates the use of Timer.
[Visual Basic]
Imports system
Imports system.threading
Imports Microsoft.visualBasic
Public class timertest
Public TimeRevent AsmanualReveTevent
Public Sub New ()
TimeRevent = New ManualReveTevent (False)
DIM TIMER AS New Timer (Addressof Me.Timethod), Nothing, Timespan.Fromseconds (5), Timespan.FromSeconds (5))
Dim TiMerCallback (Addressof Me.Tick), Nothing, Timespan.Fromseconds (1), Timespan.FromSeconds (1))
End Sub 'NEW
Public Sub TimerMethod (State As Object)
Control.writeline (Controlchars.cr "Timer Invoked this Method.")
TimeRevent.set ()
End Sub 'TimerMethod
Public Sub Tick (State As Object)
Console.write (".")
End Sub 'Tick
Public Shared Sub Main ()
Dim test as new timetest ()
Console.writeline ("The Timer Has Started and Will Count for Five Seconds)
Test.TimeRevent.waitone ()
Console.writeline ("... and control returned to the primary thread.")
End Sub 'Main
End Class' Timertest
[C #]
Using system;
Using system.threading;
Public class timertest {
Public ManualReveTevent TimeRevent;
Public timertest () {
TIMEREVENT = New ManualReveTevent (false);
Timer Timer = New Timer
New TimerCallback (this.timermethod),
NULL,
Timespan.fromseconds (5),
Timespan.fromseconds (5)
);
Timer ticktimer = new timer
New TimerCallback (this.tick), NULL,
Timespan.fromseconds (1),
Timespan.fromseconds (1)
);
}
Public void timermethod (Object State) {
Console.writeline ("/ Rthe Timer Invoked this Method.");
TimeRevent.set ();
}
Public void Tick (Object State) {
Console.write (".");
}
Public static void main () {
TimerTest Test = New TimelTest ();
Console.Writeline ("The Timer Has Started and Will Count for Five Seconds);
Test.TimeRevent.waitone ();
Console.writeline ("... and control returned to the primary thread.");
}
}
Monitor [c #]
The Monitor object will open the ability to access the code area by using the Monitor.Enter, Monitor.TryEnter, and Monitor.exit methods. After getting a lock on the code area, you can use Monitor.Wait, Monitor.pulse and Monitor.pulseall methods. If the lock is suspended, Wait releases the lock and waits for notification. When Wait receives a notification, it will return and get the lock again. Pulse and Pulseall will signal to wait for the next thread in the queue to continue.
Note that the difference between Monitor and WaitHandle objects is very important. The Monitor object is completely managed, fully portable, and may be more effective in operating system resources. The WaitHandle object indicates that the operating system can wait for the object, very useful for synchronization between managed and non-hosting code, and disclose some advanced operating system functions (such as the ability to wait many objects).
The following code example illustrates the combination of the Monitor class (compiler keyword implementation) and the interlocked class.
[Visual Basic]
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", 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 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 thrtows the thread order.
IF threadnum mod 2 = 0 THEN
Thread.sleep (2000)
END IF
Console.Writeline ("Start Unsynched Resource Access", 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, NEXT THREADNUM
'Wait Until this Waithandle is signal.
askAINCOPSAREDONE.WAITONE ()
Control.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, NEXT THREADNUM
'Wait Until this Waithandle is signal.
askAINCOPSAREDONE.WAITONE ()
Console.Writeline (Controlchars.Tab Controlchars.cr "All unsynchronized.") 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 Increment 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 subnencupdateresource (state as [object])
'This Calls The Internal Synchronized 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 Increment 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
[C #]
Using system;
Using system.threading;
// NOTE: The Class whose Internal public Member is the synchronizing method // is not public; None of the client code.
// 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", Threadnum);
Thread.sleep (200);
Console.writeline ("Stop synched resource access (thread = {0})", threadnum);
}
}
}
// WITHOUT The LOCK, The Method Is Called in 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", Threadnum);
Thread.sleep (200);
Console.writeline ("Stop unsynched resource access (thread = {0})", threadnum);
}
}
PUBLIC CLASS App {
Static int32 NumasyncOPS = 5;
Static AutoreteTevent Asyncopsaredone = New AutoreteEvent (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");
// 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.
AsyncopsaredOadone.waitone ();
Console.writeline ("/ T / Nall Unsynchronized Thread Operations Have COMPLETED.")
}
// The callback method's signature must match what of a system.threading.timerCallback
// delegate (it takes an object parameter and return ".
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 Increment Value Has Been
// Stored Into The Variable.
IF (Interlocked.Decrement (Ref NumasyncOps) == 0)
AsyncopsaredOadone.set ();
// announce to main That in Fact All Thread Calls Are Done.
}
// The callback method's signature must match what of a system.threading.timerCallback
// delegate (it takes an object parameter and return ".
Static void unsyncupdateresource (object state) {
// this Calls The Internal Synchronized 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 Increment Value Has Been
// stored Into the variable.if (Interlocked.Decrement (Ref NumasyncOps) == 0)
AsyncopsaredOadone.set ();
// announce to main That in Fact All Thread Calls Are Done.
}
}
Waithandle
The WaitHandle class package Win32 synchronization handle and is used to indicate all synchronization objects that allow multiple wait operations in the running library. It should be noted that although the WaitHandle object represents an operating system synchronization object, it is not as good as Monitor's portability; Monitor is fully managed, in some cases more effective in use of operating system resources. .
ManualResetEvent
Use the ManualResetEvent class to wait for a thread until an event is called by calling ManualRestEvent.SET. ManualRetevent will always maintain the status of the signal until it explicitly sets it to the state of the unpredictable signal via the reset method. For any number of waiting threads or subsequently starting the thread waiting for the specified event object by calling a wait function, they can be released when the object is in the state of signal. ManualRetevent corresponds to the Win32 CreateEvent call and specifies the BmanualReset parameter to TRUE.
AutoreteEvent
Using the AutoreteTevent class allows a thread to wait until an event passes it to the status of the signal by calling AutoReSetEvent.SET. Unlike ManualRetevent, AutoreseTevent is automatically reset by the system to the unproced signal by the system after a single wait thread is released. If no thread is waiting, the status of the event object will remain in the status of the signal. AutoreteTevent corresponds to the Win32 CreateEvent call and specifies the BmanualReSet parameter to false.