I am having some strange thread synchronization problems that require me to
better understand the intricacies of Monitor.Wait/Pulse.
I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock block
protecting a resource. Thread 2 and 3 also have a SyncLock block protecting
the same resource and after executing some code in their blocks they both do
a Monitor.Pulse to hand of the locked resource back to thread 1.
While thread 1 has the resource locked both thread 2 and 3 are blocked at
the beginning of their SyncLock waiting for the resource to be released. The
question is: When thread 1 does a Monitor.Wait what determines the order of
which thread 2 or 3 is allowed to enter their SyncLock? And if thread 2 gets
the resource and then releases it with a Monitor.Pulse, will thread 3 then
get the resource or will thread 1 get it first?
Thanks
Perry 12 5248
Since .Net Managed threads are backed by native operating system thread
objects, then the operating system decides which thread executes in what
order based on the time slots it has provided. The only way to influence the
order of execution is to muck with Thread Priorities, which is generally
considered a Bad Thing. When Thread1 calls Wait on the monitor object, all
it is doing is giving up the remainder of it's time slot, and telling the OS
it can switch to a different thread. The Monitor object adds items to a
queue whenever they call Wait(), so you can be pretty sure that the waiting
threads will be signaled in the order they originally executed, but you
really have no control over when a specific thread will reach that Wait()
statement.
"Perecli Manole" wrote: I am having some strange thread synchronization problems that require me to better understand the intricacies of Monitor.Wait/Pulse.
I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock block protecting a resource. Thread 2 and 3 also have a SyncLock block protecting the same resource and after executing some code in their blocks they both do a Monitor.Pulse to hand of the locked resource back to thread 1.
While thread 1 has the resource locked both thread 2 and 3 are blocked at the beginning of their SyncLock waiting for the resource to be released. The question is: When thread 1 does a Monitor.Wait what determines the order of which thread 2 or 3 is allowed to enter their SyncLock? And if thread 2 gets the resource and then releases it with a Monitor.Pulse, will thread 3 then get the resource or will thread 1 get it first?
Thanks Perry
The problem I am having is that both threads 2 and 3 are executing their
SyncLock block before returning the resource to thread 1. I was under the
assumption that as soon as either thread 2 or 3 executes its SyncLock block
(both containing a .Pulse statement) control would be given back to thread 1
as soon as either thread 2 or 3 is finished but not both. Since thread 2 and
3 where both waiting at the beginning of the SyncLock statement for the
resource to be released by thread 1, they seem to both execute before
relinquishing the resource. How can have either thread 2 or 3 (whichever
gets there first) execute but not both before the resource is returned to
thread 1.
Thanks
Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message
news:F3******** *************** ***********@mic rosoft.com... Since .Net Managed threads are backed by native operating system thread objects, then the operating system decides which thread executes in what order based on the time slots it has provided. The only way to influence the order of execution is to muck with Thread Priorities, which is generally considered a Bad Thing. When Thread1 calls Wait on the monitor object, all it is doing is giving up the remainder of it's time slot, and telling the OS it can switch to a different thread. The Monitor object adds items to a queue whenever they call Wait(), so you can be pretty sure that the waiting threads will be signaled in the order they originally executed, but you really have no control over when a specific thread will reach that Wait() statement. "Perecli Manole" wrote:
I am having some strange thread synchronization problems that require me to better understand the intricacies of Monitor.Wait/Pulse.
I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock block protecting a resource. Thread 2 and 3 also have a SyncLock block protecting the same resource and after executing some code in their blocks they both do a Monitor.Pulse to hand of the locked resource back to thread 1.
While thread 1 has the resource locked both thread 2 and 3 are blocked at the beginning of their SyncLock waiting for the resource to be released. The question is: When thread 1 does a Monitor.Wait what determines the order of which thread 2 or 3 is allowed to enter their SyncLock? And if thread 2 gets the resource and then releases it with a Monitor.Pulse, will thread 3 then get the resource or will thread 1 get it first?
Thanks Perry
Could you also answer the more important last question I posed in my last
post?
"And if thread 2 gets the resource and then releases it with a
Monitor.Pulse, will thread 3 then get the resource or will thread 1 get it
first?"
Thanks
Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message
news:F3******** *************** ***********@mic rosoft.com... Since .Net Managed threads are backed by native operating system thread objects, then the operating system decides which thread executes in what order based on the time slots it has provided. The only way to influence the order of execution is to muck with Thread Priorities, which is generally considered a Bad Thing. When Thread1 calls Wait on the monitor object, all it is doing is giving up the remainder of it's time slot, and telling the OS it can switch to a different thread. The Monitor object adds items to a queue whenever they call Wait(), so you can be pretty sure that the waiting threads will be signaled in the order they originally executed, but you really have no control over when a specific thread will reach that Wait() statement. "Perecli Manole" wrote:
I am having some strange thread synchronization problems that require me to better understand the intricacies of Monitor.Wait/Pulse.
I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock block protecting a resource. Thread 2 and 3 also have a SyncLock block protecting the same resource and after executing some code in their blocks they both do a Monitor.Pulse to hand of the locked resource back to thread 1.
While thread 1 has the resource locked both thread 2 and 3 are blocked at the beginning of their SyncLock waiting for the resource to be released. The question is: When thread 1 does a Monitor.Wait what determines the order of which thread 2 or 3 is allowed to enter their SyncLock? And if thread 2 gets the resource and then releases it with a Monitor.Pulse, will thread 3 then get the resource or will thread 1 get it first?
Thanks Perry
Okay, I think I understand more of your issue now. I'll see if I can explain
generally how Monitor Deals with Wait() and Pulse()/PulseAll() calls:
Whenever you call Monitor.Wait(), the thread that makes the call gets put
into a Wait Queue, and releases the lock on the monitored object. At this
point another thread may acquire the lock, and even call Wait() itself. Once
a thread calls Pulse() on the Monitor, the first thread in the Wait Queue
gets moved into the Lock Queue (if you use PulseAll() then all of the threads
in the Wait Queue get moved to the lock queue). Once the thread that called
Pulse() is done, the next item in the Lock Queue will get the lock.
I think the problem your running into comes from the fact that Thread 1 is
being put in the Lock Queue behind Thread 2 or Thread 3 (depending on which
got the lock on the object after Thread1 called Wait()).
I think, to directly answer your question below, that after Thread 2 calls
Pulse, then Thread 3 will get the object next, followed by Thread 1. At
least that is assuming the order of the threads is constant, which you can't
always rely on (see my original response).
Does that make sense?
"Perecli Manole" wrote: Could you also answer the more important last question I posed in my last post?
"And if thread 2 gets the resource and then releases it with a Monitor.Pulse, will thread 3 then get the resource or will thread 1 get it first?"
Thanks Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message news:F3******** *************** ***********@mic rosoft.com... Since .Net Managed threads are backed by native operating system thread objects, then the operating system decides which thread executes in what order based on the time slots it has provided. The only way to influence the order of execution is to muck with Thread Priorities, which is generally considered a Bad Thing. When Thread1 calls Wait on the monitor object, all it is doing is giving up the remainder of it's time slot, and telling the OS it can switch to a different thread. The Monitor object adds items to a queue whenever they call Wait(), so you can be pretty sure that the waiting threads will be signaled in the order they originally executed, but you really have no control over when a specific thread will reach that Wait() statement. "Perecli Manole" wrote:
I am having some strange thread synchronization problems that require me to better understand the intricacies of Monitor.Wait/Pulse.
I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock block protecting a resource. Thread 2 and 3 also have a SyncLock block protecting the same resource and after executing some code in their blocks they both do a Monitor.Pulse to hand of the locked resource back to thread 1.
While thread 1 has the resource locked both thread 2 and 3 are blocked at the beginning of their SyncLock waiting for the resource to be released. The question is: When thread 1 does a Monitor.Wait what determines the order of which thread 2 or 3 is allowed to enter their SyncLock? And if thread 2 gets the resource and then releases it with a Monitor.Pulse, will thread 3 then get the resource or will thread 1 get it first?
Thanks Perry
Thank you for the detail description, that explains the unpredictable
behavior I am experiencing.
But, in order for my application to work properly, I absolutely need the
waiting thread (Thread 1) to be the next thread that aquires the lock after
either Thread 2 or 3 pulse. Thread 1 MUST be checked with after every and
any pulse from any other thread. How can I achieve this even if it has to be
done with a different mechanism?
Thanks
Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message
news:FF******** *************** ***********@mic rosoft.com... Okay, I think I understand more of your issue now. I'll see if I can explain generally how Monitor Deals with Wait() and Pulse()/PulseAll() calls:
Whenever you call Monitor.Wait(), the thread that makes the call gets put into a Wait Queue, and releases the lock on the monitored object. At this point another thread may acquire the lock, and even call Wait() itself. Once a thread calls Pulse() on the Monitor, the first thread in the Wait Queue gets moved into the Lock Queue (if you use PulseAll() then all of the threads in the Wait Queue get moved to the lock queue). Once the thread that called Pulse() is done, the next item in the Lock Queue will get the lock.
I think the problem your running into comes from the fact that Thread 1 is being put in the Lock Queue behind Thread 2 or Thread 3 (depending on which got the lock on the object after Thread1 called Wait()).
I think, to directly answer your question below, that after Thread 2 calls Pulse, then Thread 3 will get the object next, followed by Thread 1. At least that is assuming the order of the threads is constant, which you can't always rely on (see my original response).
Does that make sense?
"Perecli Manole" wrote:
Could you also answer the more important last question I posed in my last post?
"And if thread 2 gets the resource and then releases it with a Monitor.Pulse, will thread 3 then get the resource or will thread 1 get it first?"
Thanks Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message news:F3******** *************** ***********@mic rosoft.com... > Since .Net Managed threads are backed by native operating system thread > objects, then the operating system decides which thread executes in > what > order based on the time slots it has provided. The only way to > influence > the > order of execution is to muck with Thread Priorities, which is > generally > considered a Bad Thing. When Thread1 calls Wait on the monitor object, > all > it is doing is giving up the remainder of it's time slot, and telling > the > OS > it can switch to a different thread. The Monitor object adds items to > a > queue whenever they call Wait(), so you can be pretty sure that the > waiting > threads will be signaled in the order they originally executed, but you > really have no control over when a specific thread will reach that > Wait() > statement. > > > > "Perecli Manole" wrote: > >> I am having some strange thread synchronization problems that require >> me >> to >> better understand the intricacies of Monitor.Wait/Pulse. >> >> I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock block >> protecting a resource. Thread 2 and 3 also have a SyncLock block >> protecting >> the same resource and after executing some code in their blocks they >> both >> do >> a Monitor.Pulse to hand of the locked resource back to thread 1. >> >> While thread 1 has the resource locked both thread 2 and 3 are blocked >> at >> the beginning of their SyncLock waiting for the resource to be >> released. >> The >> question is: When thread 1 does a Monitor.Wait what determines the >> order >> of >> which thread 2 or 3 is allowed to enter their SyncLock? And if thread >> 2 >> gets >> the resource and then releases it with a Monitor.Pulse, will thread 3 >> then >> get the resource or will thread 1 get it first? >> >> Thanks >> Perry >> >> >>
Well, my first suggestion might be to utilize a WaitHandle derived object
(Either a ManualResetEven t or AutoResetEvent most likely). WaitHandles
provide similar signalling to what is available with the Monitor class, but
the fact that you can manually reset an event means that other threads which
may call Wait on the handle will not block on that call until the handle is
reset.
For your description, it sounds like you may want to consider creating two
WaitHandle objects, one for Thread2 and one for Thread3, then in Thread1 call
the static WaitHandle.Wait Any() passing in an array with both of those
objects. Once Thread2 or Thread3 signals thier handle (using Set()) then
Thread1 will pick back up.
WaitHandle includes WaitOne, which waits for a single WaitHandle object to
be signaled, WaitAny, which waits for any in an array of WaitHandles to be
signaled, and WaitAll, which waits for all WaitHandles in an array to be
signaled. The instances include the Set/Reset methods, but also have a
SignalAndWait method, which allows you to signal one WaitHandle, and Wait on
another (as a single operation). It seems like some experimenting with these
might give you the some decent results.
Looking at your original post again, it looks like this example from Juval
Lowy's "Programmin g .Net Components" 2nd ed. may be helpful. He calls this a
"Rendezvous Helper", and describes it as a way to allow two threads to do
work independently, and then wait for one another to to complete before
moving on... For what it is worth here is the code (hope C# is okay):
public class Rendezvous
{
AutoResetEvent m_First = new AutoResetEvent( true);
AutoResetEvent m_Event1 = new AutoResetEvent( false);
AutoResetEvent m_Event2 = new AutoResetEvent( false);
public void Wait( )
{
bool first = m_First.WaitOne (TimeSpan.Zero, false);
if(first)
{
WaitHandle.Sign alAndWait(m_Eve nt1,m_Event2);
}
else
{
WaitHandle.Sign alAndWait(m_Eve nt2,m_Event1);
}
}
public void Reset( )
{
m_First.Set( );
}
}
Here's a usage sample:
public class RendezvousDemo
{
Rendezvous m_Rendezvous = new Rendezvous( );
public void ThreadMethod1( )
{
//Do some work, then
m_Rendezvous.Wa it( );
//Continue executing
}
public void ThreadMethod2( )
{
//Do some work, then
m_Rendezvous.Wa it( );
//Continue executing
}
}
RendezvousDemo demo = new RendezvousDemo( );
Thread thread1 = new Thread(demo.Thr eadMethod1);
thread1.Start( );
Thread thread2 = new Thread(demo.Thr eadMethod2);
thread2.Start( );
Basically what this boils down to is that thread1 and thread2 are started,
and whichever one finishes first is blocked until the other is finished, at
which point they both continue.
I'm not sure if the example is too abstract for your needs, but hopefully it
gives you enough to tinker with.
"Perecli Manole" wrote: Thank you for the detail description, that explains the unpredictable behavior I am experiencing.
But, in order for my application to work properly, I absolutely need the waiting thread (Thread 1) to be the next thread that aquires the lock after either Thread 2 or 3 pulse. Thread 1 MUST be checked with after every and any pulse from any other thread. How can I achieve this even if it has to be done with a different mechanism?
Thanks Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message news:FF******** *************** ***********@mic rosoft.com... Okay, I think I understand more of your issue now. I'll see if I can explain generally how Monitor Deals with Wait() and Pulse()/PulseAll() calls:
Whenever you call Monitor.Wait(), the thread that makes the call gets put into a Wait Queue, and releases the lock on the monitored object. At this point another thread may acquire the lock, and even call Wait() itself. Once a thread calls Pulse() on the Monitor, the first thread in the Wait Queue gets moved into the Lock Queue (if you use PulseAll() then all of the threads in the Wait Queue get moved to the lock queue). Once the thread that called Pulse() is done, the next item in the Lock Queue will get the lock.
I think the problem your running into comes from the fact that Thread 1 is being put in the Lock Queue behind Thread 2 or Thread 3 (depending on which got the lock on the object after Thread1 called Wait()).
I think, to directly answer your question below, that after Thread 2 calls Pulse, then Thread 3 will get the object next, followed by Thread 1. At least that is assuming the order of the threads is constant, which you can't always rely on (see my original response).
Does that make sense?
"Perecli Manole" wrote:
Could you also answer the more important last question I posed in my last post?
"And if thread 2 gets the resource and then releases it with a Monitor.Pulse, will thread 3 then get the resource or will thread 1 get it first?"
Thanks Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message news:F3******** *************** ***********@mic rosoft.com... > Since .Net Managed threads are backed by native operating system thread > objects, then the operating system decides which thread executes in > what > order based on the time slots it has provided. The only way to > influence > the > order of execution is to muck with Thread Priorities, which is > generally > considered a Bad Thing. When Thread1 calls Wait on the monitor object, > all > it is doing is giving up the remainder of it's time slot, and telling > the > OS > it can switch to a different thread. The Monitor object adds items to > a > queue whenever they call Wait(), so you can be pretty sure that the > waiting > threads will be signaled in the order they originally executed, but you > really have no control over when a specific thread will reach that > Wait() > statement. > > > > "Perecli Manole" wrote: > >> I am having some strange thread synchronization problems that require >> me >> to >> better understand the intricacies of Monitor.Wait/Pulse. >> >> I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock block >> protecting a resource. Thread 2 and 3 also have a SyncLock block >> protecting >> the same resource and after executing some code in their blocks they >> both >> do >> a Monitor.Pulse to hand of the locked resource back to thread 1. >> >> While thread 1 has the resource locked both thread 2 and 3 are blocked >> at >> the beginning of their SyncLock waiting for the resource to be >> released. >> The >> question is: When thread 1 does a Monitor.Wait what determines the >> order >> of >> which thread 2 or 3 is allowed to enter their SyncLock? And if thread >> 2 >> gets >> the resource and then releases it with a Monitor.Pulse, will thread 3 >> then >> get the resource or will thread 1 get it first? >> >> Thanks >> Perry >> >> >>
I had the same thought as you so I tried the AutoResetEvent. This approach
has a strange side effect though. The WaitHandle, I'am guessing, seems to
prevent the SerialPort.Data Received event from fireing so thread 2 and above
are not being called causing the WaitOne to always expire on the timout.
When using the Monitor.Wait function instead the event is raised again. Can
this be explained? Here a snipit that shows the basics:
'global
Private _ARE1 As New AutoResetEvent( False)
Private _ARE2 As New AutoResetEvent( False)
'---------------------- transmit tread 1 ----------------------
SyncLock _objTxRxSync
_objSerialPort. Write(objTxPack et.Bytes, 0, objCurrTxPacket .Bytes.Length)
_objTxRxSync.As sertedPacket = objTxPacket
_objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Echo
If _ARE1.WaitOne(P ACKET_ECHO_TIME OUT, True) Then
If objTxPacket.Nee dsPacketRespons e Then
_objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Response
_ARE2.WaitOne(P ACKET_RESPONSE_ TIMEOUT, True)
End If
End If
End SyncLock
'------------------receive threads 2,3,n.... ---------------------
SyncLock _objTxRxSync
If _objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Echo AndAlso
_objTxRxSync.As sertedPacket.Eq uals(_objRxPack et) Then
RaiseCallBackEv ent(_objTxRxSyn c.AssertedPacke t)
_ARE1.Set()
Exit Sub
End If
End SyncLock
'do some work that does not need syncronization for non echo packets only
'..............
SyncLock _objTxRxSync
If _objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Response AndAlso
_objTxRxSync.As sertedPacket.Va lidPacketRespon se(objRxPacket) Then
_ARE2.Set()
End If
End SyncLock
RaiseCallBackEv ent(objRxPacket )
Thanks
Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message
news:10******** *************** ***********@mic rosoft.com... Well, my first suggestion might be to utilize a WaitHandle derived object (Either a ManualResetEven t or AutoResetEvent most likely). WaitHandles provide similar signalling to what is available with the Monitor class, but the fact that you can manually reset an event means that other threads which may call Wait on the handle will not block on that call until the handle is reset.
For your description, it sounds like you may want to consider creating two WaitHandle objects, one for Thread2 and one for Thread3, then in Thread1 call the static WaitHandle.Wait Any() passing in an array with both of those objects. Once Thread2 or Thread3 signals thier handle (using Set()) then Thread1 will pick back up.
WaitHandle includes WaitOne, which waits for a single WaitHandle object to be signaled, WaitAny, which waits for any in an array of WaitHandles to be signaled, and WaitAll, which waits for all WaitHandles in an array to be signaled. The instances include the Set/Reset methods, but also have a SignalAndWait method, which allows you to signal one WaitHandle, and Wait on another (as a single operation). It seems like some experimenting with these might give you the some decent results.
Looking at your original post again, it looks like this example from Juval Lowy's "Programmin g .Net Components" 2nd ed. may be helpful. He calls this a "Rendezvous Helper", and describes it as a way to allow two threads to do work independently, and then wait for one another to to complete before moving on... For what it is worth here is the code (hope C# is okay):
public class Rendezvous { AutoResetEvent m_First = new AutoResetEvent( true); AutoResetEvent m_Event1 = new AutoResetEvent( false); AutoResetEvent m_Event2 = new AutoResetEvent( false);
public void Wait( ) { bool first = m_First.WaitOne (TimeSpan.Zero, false); if(first) { WaitHandle.Sign alAndWait(m_Eve nt1,m_Event2); } else { WaitHandle.Sign alAndWait(m_Eve nt2,m_Event1); } } public void Reset( ) { m_First.Set( ); } }
Here's a usage sample:
public class RendezvousDemo { Rendezvous m_Rendezvous = new Rendezvous( );
public void ThreadMethod1( ) { //Do some work, then m_Rendezvous.Wa it( ); //Continue executing } public void ThreadMethod2( ) { //Do some work, then m_Rendezvous.Wa it( ); //Continue executing
} } RendezvousDemo demo = new RendezvousDemo( ); Thread thread1 = new Thread(demo.Thr eadMethod1); thread1.Start( );
Thread thread2 = new Thread(demo.Thr eadMethod2); thread2.Start( );
Basically what this boils down to is that thread1 and thread2 are started, and whichever one finishes first is blocked until the other is finished, at which point they both continue.
I'm not sure if the example is too abstract for your needs, but hopefully it gives you enough to tinker with.
"Perecli Manole" wrote:
Thank you for the detail description, that explains the unpredictable behavior I am experiencing.
But, in order for my application to work properly, I absolutely need the waiting thread (Thread 1) to be the next thread that aquires the lock after either Thread 2 or 3 pulse. Thread 1 MUST be checked with after every and any pulse from any other thread. How can I achieve this even if it has to be done with a different mechanism?
Thanks Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message news:FF******** *************** ***********@mic rosoft.com... > Okay, I think I understand more of your issue now. I'll see if I can > explain > generally how Monitor Deals with Wait() and Pulse()/PulseAll() calls: > > Whenever you call Monitor.Wait(), the thread that makes the call gets > put > into a Wait Queue, and releases the lock on the monitored object. At > this > point another thread may acquire the lock, and even call Wait() itself. > Once > a thread calls Pulse() on the Monitor, the first thread in the Wait > Queue > gets moved into the Lock Queue (if you use PulseAll() then all of the > threads > in the Wait Queue get moved to the lock queue). Once the thread that > called > Pulse() is done, the next item in the Lock Queue will get the lock. > > I think the problem your running into comes from the fact that Thread 1 > is > being put in the Lock Queue behind Thread 2 or Thread 3 (depending on > which > got the lock on the object after Thread1 called Wait()). > > I think, to directly answer your question below, that after Thread 2 > calls > Pulse, then Thread 3 will get the object next, followed by Thread 1. > At > least that is assuming the order of the threads is constant, which you > can't > always rely on (see my original response). > > Does that make sense? > > "Perecli Manole" wrote: > >> Could you also answer the more important last question I posed in my >> last >> post? >> >> "And if thread 2 gets the resource and then releases it with a >> Monitor.Pulse, will thread 3 then get the resource or will thread 1 >> get >> it >> first?" >> >> Thanks >> Perry >> >> >> "Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in >> message >> news:F3******** *************** ***********@mic rosoft.com... >> > Since .Net Managed threads are backed by native operating system >> > thread >> > objects, then the operating system decides which thread executes in >> > what >> > order based on the time slots it has provided. The only way to >> > influence >> > the >> > order of execution is to muck with Thread Priorities, which is >> > generally >> > considered a Bad Thing. When Thread1 calls Wait on the monitor >> > object, >> > all >> > it is doing is giving up the remainder of it's time slot, and >> > telling >> > the >> > OS >> > it can switch to a different thread. The Monitor object adds items >> > to >> > a >> > queue whenever they call Wait(), so you can be pretty sure that the >> > waiting >> > threads will be signaled in the order they originally executed, but >> > you >> > really have no control over when a specific thread will reach that >> > Wait() >> > statement. >> > >> > >> > >> > "Perecli Manole" wrote: >> > >> >> I am having some strange thread synchronization problems that >> >> require >> >> me >> >> to >> >> better understand the intricacies of Monitor.Wait/Pulse. >> >> >> >> I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock block >> >> protecting a resource. Thread 2 and 3 also have a SyncLock block >> >> protecting >> >> the same resource and after executing some code in their blocks >> >> they >> >> both >> >> do >> >> a Monitor.Pulse to hand of the locked resource back to thread 1. >> >> >> >> While thread 1 has the resource locked both thread 2 and 3 are >> >> blocked >> >> at >> >> the beginning of their SyncLock waiting for the resource to be >> >> released. >> >> The >> >> question is: When thread 1 does a Monitor.Wait what determines the >> >> order >> >> of >> >> which thread 2 or 3 is allowed to enter their SyncLock? And if >> >> thread >> >> 2 >> >> gets >> >> the resource and then releases it with a Monitor.Pulse, will thread >> >> 3 >> >> then >> >> get the resource or will thread 1 get it first? >> >> >> >> Thanks >> >> Perry >> >> >> >> >> >> >> >> >>
I think the problem is that you are calling the Wait() mehod on your wait
handle within your SynLock block. The one thing Monitor.Wait does that you
don't get with WaitHandles is that it releases the Lock on the Object you
call Wait on.
I would say break it out into two SynLock groups in Thread 1, one locking
the resources just prior to calling WaitHandle.Wait (), and the other after
the Wait returns.
You'll need to limit the scope of the SynLock in Thread's 2 & 3 as well.
I'm afraid, though, that you may run into a similar problem as the one you
were experiencing with the Monitor object. You may want to consider using
the Semiphore class to allow 2 classes to access your _objTxRxSync object at
a time. You would probably also need to use either a WaitHandle, or a global
(and locked) variable to make sure that Threads 2 & 3 don't do their thing
until Thread 1 is ready. Adding the Semiphore will give you the ability to
make sure only two threads will be working with the resources at a time,
though.
Does this make any sense?
Casey
"Perecli Manole" wrote: I had the same thought as you so I tried the AutoResetEvent. This approach has a strange side effect though. The WaitHandle, I'am guessing, seems to prevent the SerialPort.Data Received event from fireing so thread 2 and above are not being called causing the WaitOne to always expire on the timout. When using the Monitor.Wait function instead the event is raised again. Can this be explained? Here a snipit that shows the basics:
'global Private _ARE1 As New AutoResetEvent( False) Private _ARE2 As New AutoResetEvent( False)
'---------------------- transmit tread 1 ---------------------- SyncLock _objTxRxSync _objSerialPort. Write(objTxPack et.Bytes, 0, objCurrTxPacket .Bytes.Length) _objTxRxSync.As sertedPacket = objTxPacket _objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Echo If _ARE1.WaitOne(P ACKET_ECHO_TIME OUT, True) Then If objTxPacket.Nee dsPacketRespons e Then _objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Response _ARE2.WaitOne(P ACKET_RESPONSE_ TIMEOUT, True) End If End If End SyncLock
'------------------receive threads 2,3,n.... --------------------- SyncLock _objTxRxSync If _objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Echo AndAlso _objTxRxSync.As sertedPacket.Eq uals(_objRxPack et) Then RaiseCallBackEv ent(_objTxRxSyn c.AssertedPacke t) _ARE1.Set() Exit Sub End If End SyncLock
'do some work that does not need syncronization for non echo packets only '..............
SyncLock _objTxRxSync If _objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Response AndAlso _objTxRxSync.As sertedPacket.Va lidPacketRespon se(objRxPacket) Then _ARE2.Set() End If End SyncLock
RaiseCallBackEv ent(objRxPacket ) Thanks Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message news:10******** *************** ***********@mic rosoft.com... Well, my first suggestion might be to utilize a WaitHandle derived object (Either a ManualResetEven t or AutoResetEvent most likely). WaitHandles provide similar signalling to what is available with the Monitor class, but the fact that you can manually reset an event means that other threads which may call Wait on the handle will not block on that call until the handle is reset.
For your description, it sounds like you may want to consider creating two WaitHandle objects, one for Thread2 and one for Thread3, then in Thread1 call the static WaitHandle.Wait Any() passing in an array with both of those objects. Once Thread2 or Thread3 signals thier handle (using Set()) then Thread1 will pick back up.
WaitHandle includes WaitOne, which waits for a single WaitHandle object to be signaled, WaitAny, which waits for any in an array of WaitHandles to be signaled, and WaitAll, which waits for all WaitHandles in an array to be signaled. The instances include the Set/Reset methods, but also have a SignalAndWait method, which allows you to signal one WaitHandle, and Wait on another (as a single operation). It seems like some experimenting with these might give you the some decent results.
Looking at your original post again, it looks like this example from Juval Lowy's "Programmin g .Net Components" 2nd ed. may be helpful. He calls this a "Rendezvous Helper", and describes it as a way to allow two threads to do work independently, and then wait for one another to to complete before moving on... For what it is worth here is the code (hope C# is okay):
public class Rendezvous { AutoResetEvent m_First = new AutoResetEvent( true); AutoResetEvent m_Event1 = new AutoResetEvent( false); AutoResetEvent m_Event2 = new AutoResetEvent( false);
public void Wait( ) { bool first = m_First.WaitOne (TimeSpan.Zero, false); if(first) { WaitHandle.Sign alAndWait(m_Eve nt1,m_Event2); } else { WaitHandle.Sign alAndWait(m_Eve nt2,m_Event1); } } public void Reset( ) { m_First.Set( ); } }
Here's a usage sample:
public class RendezvousDemo { Rendezvous m_Rendezvous = new Rendezvous( );
public void ThreadMethod1( ) { //Do some work, then m_Rendezvous.Wa it( ); //Continue executing } public void ThreadMethod2( ) { //Do some work, then m_Rendezvous.Wa it( ); //Continue executing
} } RendezvousDemo demo = new RendezvousDemo( ); Thread thread1 = new Thread(demo.Thr eadMethod1); thread1.Start( );
Thread thread2 = new Thread(demo.Thr eadMethod2); thread2.Start( );
Basically what this boils down to is that thread1 and thread2 are started, and whichever one finishes first is blocked until the other is finished, at which point they both continue.
I'm not sure if the example is too abstract for your needs, but hopefully it gives you enough to tinker with.
"Perecli Manole" wrote:
Thank you for the detail description, that explains the unpredictable behavior I am experiencing.
But, in order for my application to work properly, I absolutely need the waiting thread (Thread 1) to be the next thread that aquires the lock after either Thread 2 or 3 pulse. Thread 1 MUST be checked with after every and any pulse from any other thread. How can I achieve this even if it has to be done with a different mechanism?
Thanks Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message news:FF******** *************** ***********@mic rosoft.com... > Okay, I think I understand more of your issue now. I'll see if I can > explain > generally how Monitor Deals with Wait() and Pulse()/PulseAll() calls: > > Whenever you call Monitor.Wait(), the thread that makes the call gets > put > into a Wait Queue, and releases the lock on the monitored object. At > this > point another thread may acquire the lock, and even call Wait() itself. > Once > a thread calls Pulse() on the Monitor, the first thread in the Wait > Queue > gets moved into the Lock Queue (if you use PulseAll() then all of the > threads > in the Wait Queue get moved to the lock queue). Once the thread that > called > Pulse() is done, the next item in the Lock Queue will get the lock. > > I think the problem your running into comes from the fact that Thread 1 > is > being put in the Lock Queue behind Thread 2 or Thread 3 (depending on > which > got the lock on the object after Thread1 called Wait()). > > I think, to directly answer your question below, that after Thread 2 > calls > Pulse, then Thread 3 will get the object next, followed by Thread 1. > At > least that is assuming the order of the threads is constant, which you > can't > always rely on (see my original response). > > Does that make sense? > > "Perecli Manole" wrote: > >> Could you also answer the more important last question I posed in my >> last >> post? >> >> "And if thread 2 gets the resource and then releases it with a >> Monitor.Pulse, will thread 3 then get the resource or will thread 1 >> get >> it >> first?" >> >> Thanks >> Perry >> >> >> "Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in >> message >> news:F3******** *************** ***********@mic rosoft.com... >> > Since .Net Managed threads are backed by native operating system >> > thread >> > objects, then the operating system decides which thread executes in >> > what >> > order based on the time slots it has provided. The only way to >> > influence >> > the >> > order of execution is to muck with Thread Priorities, which is >> > generally >> > considered a Bad Thing. When Thread1 calls Wait on the monitor >> > object, >> > all >> > it is doing is giving up the remainder of it's time slot, and >> > telling >> > the >> > OS >> > it can switch to a different thread. The Monitor object adds items >> > to >> > a >> > queue whenever they call Wait(), so you can be pretty sure that the >> > waiting >> > threads will be signaled in the order they originally executed, but >> > you >> > really have no control over when a specific thread will reach that >> > Wait() >> > statement. >> > >> > >> > >> > "Perecli Manole" wrote: >> > >> >> I am having some strange thread synchronization problems that >> >> require >> >> me >> >> to >> >> better understand the intricacies of Monitor.Wait/Pulse. >> >> >> >> I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock block >> >> protecting a resource. Thread 2 and 3 also have a SyncLock block >> >> protecting >> >> the same resource and after executing some code in their blocks >> >> they >> >> both >> >> do >> >> a Monitor.Pulse to hand of the locked resource back to thread 1. >> >> >> >> While thread 1 has the resource locked both thread 2 and 3 are >> >> blocked >> >> at >> >> the beginning of their SyncLock waiting for the resource to be >> >> released. >> >> The >> >> question is: When thread 1 does a Monitor.Wait what determines the >> >> order >> >> of >> >> which thread 2 or 3 is allowed to enter their SyncLock? And if >> >> thread >> >> 2 >> >> gets >> >> the resource and then releases it with a Monitor.Pulse, will thread >> >> 3 >> >> then >> >> get the resource or will thread 1 get it first? >> >> >> >> Thanks >> >> Perry >> >> >> >> >> >> >> >> >>
>I think the problem is that you are calling the Wait() mehod on your wait handle within your SynLock block. The one thing Monitor.Wait does that you don't get with WaitHandles is that it releases the Lock on the Object you call Wait on.
I thought by setting the last boolean parameter in the WaitOne method to
True will allow the exit of the locking context. The documentation seems to
imply this.
_ARE1.WaitOne(P ACKET_ECHO_TIME OUT, True)
I would say break it out into two SynLock groups in Thread 1, one locking the resources just prior to calling WaitHandle.Wait (), and the other after the Wait returns.
If I break the SyncLock into two groups then the memebers of the objTxPacket
can be changed by other threads in between the SyncLocks. Also don't know
how to synclock the second WaitOne because it is in a conditional statement
that get its value from the locked object. It the object is not locked at
that point then there could be problems.
SyncLock _objTxRxSync
_objSerialPort. Write(objTxPack et.Bytes, 0, objCurrTxPacket .Bytes.Length)
_objTxRxSync.As sertedPacket = objTxPacket
_objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Echo
If _ARE1.WaitOne(P ACKET_ECHO_TIME OUT, True) Then
If objTxPacket.Nee dsPacketRespons e Then
_objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Response
_ARE2.WaitOne(P ACKET_RESPONSE_ TIMEOUT, True)
End If
End If
End SyncLock
You'll need to limit the scope of the SynLock in Thread's 2 & 3 as well.
How can I limit it any smaller that it already is?
I'm afraid, though, that you may run into a similar problem as the one you were experiencing with the Monitor object. You may want to consider using the Semiphore class to allow 2 classes to access your _objTxRxSync object at a time. You would probably also need to use either a WaitHandle, or a global (and locked) variable to make sure that Threads 2 & 3 don't do their thing until Thread 1 is ready. Adding the Semiphore will give you the ability to make sure only two threads will be working with the resources at a time, though. Does this make any sense?
Not clear how to do this.
Perry
"Perecli Manole" wrote:
I had the same thought as you so I tried the AutoResetEvent. This approach has a strange side effect though. The WaitHandle, I'am guessing, seems to prevent the SerialPort.Data Received event from fireing so thread 2 and above are not being called causing the WaitOne to always expire on the timout. When using the Monitor.Wait function instead the event is raised again. Can this be explained? Here a snipit that shows the basics:
'global Private _ARE1 As New AutoResetEvent( False) Private _ARE2 As New AutoResetEvent( False)
'---------------------- transmit tread 1 ---------------------- SyncLock _objTxRxSync _objSerialPort. Write(objTxPack et.Bytes, 0, objCurrTxPacket .Bytes.Length) _objTxRxSync.As sertedPacket = objTxPacket _objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Echo If _ARE1.WaitOne(P ACKET_ECHO_TIME OUT, True) Then If objTxPacket.Nee dsPacketRespons e Then _objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Response _ARE2.WaitOne(P ACKET_RESPONSE_ TIMEOUT, True) End If End If End SyncLock
'------------------receive threads 2,3,n.... --------------------- SyncLock _objTxRxSync If _objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Echo AndAlso _objTxRxSync.As sertedPacket.Eq uals(_objRxPack et) Then RaiseCallBackEv ent(_objTxRxSyn c.AssertedPacke t) _ARE1.Set() Exit Sub End If End SyncLock
'do some work that does not need syncronization for non echo packets only '..............
SyncLock _objTxRxSync If _objTxRxSync.Ma tchNeeded = TxRxSync.MatchT ype.Response AndAlso _objTxRxSync.As sertedPacket.Va lidPacketRespon se(objRxPacket) Then _ARE2.Set() End If End SyncLock
RaiseCallBackEv ent(objRxPacket ) Thanks Perry
"Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in message news:10******** *************** ***********@mic rosoft.com... > Well, my first suggestion might be to utilize a WaitHandle derived > object > (Either a ManualResetEven t or AutoResetEvent most likely). WaitHandles > provide similar signalling to what is available with the Monitor class, > but > the fact that you can manually reset an event means that other threads > which > may call Wait on the handle will not block on that call until the > handle > is > reset. > > For your description, it sounds like you may want to consider creating > two > WaitHandle objects, one for Thread2 and one for Thread3, then in > Thread1 > call > the static WaitHandle.Wait Any() passing in an array with both of those > objects. Once Thread2 or Thread3 signals thier handle (using Set()) > then > Thread1 will pick back up. > > WaitHandle includes WaitOne, which waits for a single WaitHandle object > to > be signaled, WaitAny, which waits for any in an array of WaitHandles to > be > signaled, and WaitAll, which waits for all WaitHandles in an array to > be > signaled. The instances include the Set/Reset methods, but also have a > SignalAndWait method, which allows you to signal one WaitHandle, and > Wait > on > another (as a single operation). It seems like some experimenting with > these > might give you the some decent results. > > Looking at your original post again, it looks like this example from > Juval > Lowy's "Programmin g .Net Components" 2nd ed. may be helpful. He calls > this a > "Rendezvous Helper", and describes it as a way to allow two threads to > do > work independently, and then wait for one another to to complete before > moving on... For what it is worth here is the code (hope C# is okay): > > public class Rendezvous > { > AutoResetEvent m_First = new AutoResetEvent( true); > AutoResetEvent m_Event1 = new AutoResetEvent( false); > AutoResetEvent m_Event2 = new AutoResetEvent( false); > > public void Wait( ) > { > bool first = m_First.WaitOne (TimeSpan.Zero, false); > if(first) > { > WaitHandle.Sign alAndWait(m_Eve nt1,m_Event2); > } > else > { > WaitHandle.Sign alAndWait(m_Eve nt2,m_Event1); > } > } > public void Reset( ) > { > m_First.Set( ); > } > } > > Here's a usage sample: > > public class RendezvousDemo > { > Rendezvous m_Rendezvous = new Rendezvous( ); > > public void ThreadMethod1( ) > { > //Do some work, then > m_Rendezvous.Wa it( ); > //Continue executing > } > public void ThreadMethod2( ) > { > //Do some work, then > m_Rendezvous.Wa it( ); > //Continue executing > > } > } > RendezvousDemo demo = new RendezvousDemo( ); > Thread thread1 = new Thread(demo.Thr eadMethod1); > thread1.Start( ); > > Thread thread2 = new Thread(demo.Thr eadMethod2); > thread2.Start( ); > > Basically what this boils down to is that thread1 and thread2 are > started, > and whichever one finishes first is blocked until the other is > finished, > at > which point they both continue. > > I'm not sure if the example is too abstract for your needs, but > hopefully > it > gives you enough to tinker with. > > "Perecli Manole" wrote: > >> Thank you for the detail description, that explains the unpredictable >> behavior I am experiencing. >> >> But, in order for my application to work properly, I absolutely need >> the >> waiting thread (Thread 1) to be the next thread that aquires the lock >> after >> either Thread 2 or 3 pulse. Thread 1 MUST be checked with after every >> and >> any pulse from any other thread. How can I achieve this even if it has >> to >> be >> done with a different mechanism? >> >> Thanks >> Perry >> >> "Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in >> message >> news:FF******** *************** ***********@mic rosoft.com... >> > Okay, I think I understand more of your issue now. I'll see if I >> > can >> > explain >> > generally how Monitor Deals with Wait() and Pulse()/PulseAll() >> > calls: >> > >> > Whenever you call Monitor.Wait(), the thread that makes the call >> > gets >> > put >> > into a Wait Queue, and releases the lock on the monitored object. >> > At >> > this >> > point another thread may acquire the lock, and even call Wait() >> > itself. >> > Once >> > a thread calls Pulse() on the Monitor, the first thread in the Wait >> > Queue >> > gets moved into the Lock Queue (if you use PulseAll() then all of >> > the >> > threads >> > in the Wait Queue get moved to the lock queue). Once the thread >> > that >> > called >> > Pulse() is done, the next item in the Lock Queue will get the lock. >> > >> > I think the problem your running into comes from the fact that >> > Thread 1 >> > is >> > being put in the Lock Queue behind Thread 2 or Thread 3 (depending >> > on >> > which >> > got the lock on the object after Thread1 called Wait()). >> > >> > I think, to directly answer your question below, that after Thread 2 >> > calls >> > Pulse, then Thread 3 will get the object next, followed by Thread 1. >> > At >> > least that is assuming the order of the threads is constant, which >> > you >> > can't >> > always rely on (see my original response). >> > >> > Does that make sense? >> > >> > "Perecli Manole" wrote: >> > >> >> Could you also answer the more important last question I posed in >> >> my >> >> last >> >> post? >> >> >> >> "And if thread 2 gets the resource and then releases it with a >> >> Monitor.Pulse, will thread 3 then get the resource or will thread 1 >> >> get >> >> it >> >> first?" >> >> >> >> Thanks >> >> Perry >> >> >> >> >> >> "Casey Kramer" <Ca*********@di scussions.micro soft.com> wrote in >> >> message >> >> news:F3******** *************** ***********@mic rosoft.com... >> >> > Since .Net Managed threads are backed by native operating system >> >> > thread >> >> > objects, then the operating system decides which thread executes >> >> > in >> >> > what >> >> > order based on the time slots it has provided. The only way to >> >> > influence >> >> > the >> >> > order of execution is to muck with Thread Priorities, which is >> >> > generally >> >> > considered a Bad Thing. When Thread1 calls Wait on the monitor >> >> > object, >> >> > all >> >> > it is doing is giving up the remainder of it's time slot, and >> >> > telling >> >> > the >> >> > OS >> >> > it can switch to a different thread. The Monitor object adds >> >> > items >> >> > to >> >> > a >> >> > queue whenever they call Wait(), so you can be pretty sure that >> >> > the >> >> > waiting >> >> > threads will be signaled in the order they originally executed, >> >> > but >> >> > you >> >> > really have no control over when a specific thread will reach >> >> > that >> >> > Wait() >> >> > statement. >> >> > >> >> > >> >> > >> >> > "Perecli Manole" wrote: >> >> > >> >> >> I am having some strange thread synchronization problems that >> >> >> require >> >> >> me >> >> >> to >> >> >> better understand the intricacies of Monitor.Wait/Pulse. >> >> >> >> >> >> I have 3 threads. Thread 1 does a Monitor.Wait in a SyncLock >> >> >> block >> >> >> protecting a resource. Thread 2 and 3 also have a SyncLock block >> >> >> protecting >> >> >> the same resource and after executing some code in their blocks >> >> >> they >> >> >> both >> >> >> do >> >> >> a Monitor.Pulse to hand of the locked resource back to thread 1. >> >> >> >> >> >> While thread 1 has the resource locked both thread 2 and 3 are >> >> >> blocked >> >> >> at >> >> >> the beginning of their SyncLock waiting for the resource to be >> >> >> released. >> >> >> The >> >> >> question is: When thread 1 does a Monitor.Wait what determines >> >> >> the >> >> >> order >> >> >> of >> >> >> which thread 2 or 3 is allowed to enter their SyncLock? And if >> >> >> thread >> >> >> 2 >> >> >> gets >> >> >> the resource and then releases it with a Monitor.Pulse, will >> >> >> thread >> >> >> 3 >> >> >> then >> >> >> get the resource or will thread 1 get it first? >> >> >> >> >> >> Thanks >> >> >> Perry >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Jon Skeet [C# MVP] |
last post by:
Please excuse the cross-post - I'm pretty sure I've had interest in the
article on all the groups this is posted to.
I've finally managed to finish my article on multi-threading - at least
for the moment. I'd be *very* grateful if people with any interest in
multi-threading would read it (even just bits of it - it's somewhat
long to go...
|
by: Zach |
last post by:
Re:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/
frlrfSystemThreadingMonitorClassPulseTopic.asp
Why is the example shown there done as it is, and not as below?
(I mean the logic not the little changes in nomenclature)
using System;
using System.Threading;
using System.Collections;
|
by: Mike |
last post by:
Hello,
Here is my challenge.
I have a thread awaiting events being sent via Queue. Currently I am
checking the count and if there is a count, Dequeue() the next object
and process it. By design, however, this is inefficient usage of CPU
clocks.
A more efficient usage could be to wrap Monitor::Wait() and
|
by: Mike |
last post by:
I have to ask a stupid question regarding Monitor.
Wait() and Pulse() make be used to wait for and signal events in a
given thread.
However, neither can be used until calling within a synchronized block
between calls to Enter() and Exit().
Am I missing something when I say that it seems useless to use this
facility to synchronize...
|
by: **Developer** |
last post by:
I have a simple need that I can't seem to locate the answer to in the docs.
Most examples show how a worker thread can pass data back to the thread that
created it.
I need to do the opposite.
Suppose the worker thread displays a form and the thread that created it
wants to change that form's text occasionally.
| |
by: Bruce Wood |
last post by:
Maybe it's just late in my day, but I'm reading Jon's article on
threading, in particular how to use Monitor.Wait() and Monitor.Pulse(),
and there's something that's not sinking in. The code in question
looks like this:
public class ProducerConsumer
{
readonly object listLock = new object();
Queue queue = new Queue();
|
by: Aidal |
last post by:
Hi NG.
I'm creating a little app. that has to use a 3rd party API.
The functions in this API has no return value but trigger events like OK
or NOT OK with event args.
Where I need to use this API I must have a synchrone modul so I need to
force a synchrone look to this asynchrone model of the API.
I was thinking this would call for...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it. ...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
| |
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...
| |