What's the Difference between Manual/AutoResetEvent and Monitor?

  • Thread starter Thread starter Charles Law
  • Start date Start date
C

Charles Law

I've been using monitors a bit lately (some of you may have heard ;-) ) and
then up pop Manual and AutoResetEvents , and they look for all the world
like the same thing.

Are they interchangeable, or when should I use one over the other?

TIA

Charles
 
Charles,
I've been using monitors a bit lately (some of you may have heard ;-) ) and
then up pop Manual and AutoResetEvents , and they look for all the world
like the same thing.
Monitors are used to "synchronize access to a member or to build your own
thread management types".

Manual & Auto Reset Events are used to "signaled when an event occurs".
Are they interchangeable, or when should I use one over the other?
Yes they can be used interchangeable, and yes there are times when you
should use one over the other.


Normally I use SyncLock instead of using the Monitor directly, remember that
SyncLock is implemented in terms of Monitor. SyncLock is used to protect one
or more blocks of code from being executed simultaneously. For example if I
had a System.Collections.Queue to send requests from the Main thread to a
Worker thread. I would protect the methods where Queue.Enqueue &
Queue.Dequeue were with the same padlock object (the object passed to
Monitor/SyncLock).

I would use a Manual or Auto ResetEvent in the same class to let the worker
thread know there is work to be done.

Something like:

' untested, typed from memory.
Public Class ThreadRequestQueue

Private Readonly m_padlock As New Object
Private Readonly m_queue As New Queue
Private Readonly m_event As New AutoResetEvent(False)

' called from the Main thread
Public Sub AddRequest(ByVal request As Object)
SyncLock m_padlock
m_queue.Enqueue(Object)
End SyncLock
m_event.Set()
End Sub

' called from the Worker thread
Public Function GetRequest() As Object
' Check to see if there are already items available
SyncLock m_padlock
If m_queue.Count() > 0 Then
Return m_queue.DeQueue()
End If
End SyncLock

' Cannot block worker thread
' while waiting for the main thread to add requests
m_event.WaitOne()

' There must be an item
SyncLock m_padlock
Return m_queue.Dequeue()
End SyncLock
End Function

End Class

Hope this helps
Jay
 
Hi Jay
SyncLock is used to protect one
or more blocks of code from being executed simultaneously.

Is this different from "accessing the same variable concurrently"?

What I mean is, if I have

<code>
Public Function Read() as Long
SyncLock (m_LockObject)
Return m_Variable
End SyncLock
End Function

Public Sub Write(Value As Long)
SyncLock (m_LockObject)
m_Variable = Value
End SyncLock
End Sub
</code>

can one thread execute Read while another executes Write, so that m_Variable
can be read when it is only half updated? After all, I am not executing the
same bit of code simultaneously because they are in two different methods.

I understand that two threads cannot execute Read or Write simultaneously,
but what about Read *and* Write?

Secondly,
m_event.Set()

Isn't this just Monitor.Pulse(m_event), and
m_event.WaitOne()

Monitor.Wait(m_event) ? If so, what is there to choose between the two?

Charles
 
Charles,
Is this different from "accessing the same variable concurrently"?
...
I understand that two threads cannot execute Read or Write simultaneously,
but what about Read *and* Write?
Simultaneously and concurrently are synonymous in that only one of either
Read or Write will execute at the same time. In other words if I have 2
threads. If Thread 1 is in either Read or Write Thread 2 cannot be in
either Read or Write. Like wise if Thread 2 is in either Read or Write,
Thread 1 cannot be in either Read or Write. I'm really not sure what you are
wanting to say with "*and*".
Secondly,
Isn't this just Monitor.Pulse(m_event), and
Monitor.Wait(m_event) ?

Go back to the original statement. Monitor can be used "or to build your own
thread management types". So yes you can use Monitor to build the two Event
classes. I would not be surprised if the two Event classes are implemented
in terms of Monitor.
If so, what is there to choose between the two?
One word: Abstraction

As I said before I would use Manual or AutoResetEvent if I wanted to signal
an Event between two threads. (notice Event in the name of the class).

I would use Monitor (SyncLock really) to control access to a resource (code
block).

Hope this helps
Jay
 
Back
Top