ManualResetEvent / WaitOne

ManualResetEvent / WaitOne

am 22.08.2007 11:17:00 von PeterLarsen

Hi,

I have a problem using a ManuelResetEvent in the GUI thread while receiving
events from the Shell (new folders, rename etc).

This is what i do:

Receiving an event from the Shell.
Running some code - setting ManauelResetEvent.Reset().
The code continue - and somewhere else i test the handle
"ManuelResetEvent.WaitOne(100, true)" - still in the GUI thread.
While waiting (in WaitOne), the application receive yet another event from
the Shell - also in the main thread.

How is it possible to receive the second event while blocking the GUI thread
??

Thank you in advance
BR
Peter

RE: ManualResetEvent / WaitOne

am 23.08.2007 08:15:55 von wawang

Hi Peter,

Sorry for delayed reply.

Could you please tell me more about your scenario? Are you watching for
file system changes? Preferrably a simple but complete and reproducible
project will be great for quick troubleshooting. Thanks.


Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Re: ManualResetEvent / WaitOne

am 23.08.2007 14:35:43 von PeterLarsen

Hi Walter,

I will try to create a small demo project within a few days !!

/Peter

Re: ManualResetEvent / WaitOne

am 23.08.2007 14:53:58 von Marc Gravell

First - I don't know a great deal about the shell messages in
question, so this only covers general principal...

I think part of the problem is that blocking the UI thread is never a
good idea.

Would it be possible to simply disable the UI (i.e. set .Enabled =
false on a few strategic controls), do the waiting on a pool thread,
and then call-back (Control.Invoke) onto the UI thread to wake it all
back up and re-enable the UI?

Alternatively, Application.DoEvents() exists, which should allow it to
process enough of the message-queue to get your external messages -
but you can't really predict what messages it is going to handle doing
this. I would tend to use the first approach if possible.

Marc

Re: ManualResetEvent / WaitOne

am 23.08.2007 15:26:03 von PeterLarsen

Hi Marc,

Shell events don't differ from invoking to the GUI thread.

What i don't understand is that while blocking the GUI thread, the GUI
thread decides to continue somewhere else. And i'm not talking about holding
the thread for a long time of periode, WaitOne(0, true) would also raise
this issue.

/Peter

Re: ManualResetEvent / WaitOne

am 23.08.2007 15:47:07 von Marc Gravell

Ahah! it becomes clearer... I read the line (below) as "this is what I
want to achieve", rather than "this is darned freaky, why is it
happening?"

> How is it possible to receive the second event while blocking the
> GUI thread ??

Yes, that is odd... are you sure that it is actually the GUI thread
that is invoking? It could be the shell events are arriving on an
arbitrary thread? Worth checking the ManagedThreadId in the GUI code,
and in the method that is being triggered... are they
one-and-the-same?

Marc

Re: ManualResetEvent / WaitOne

am 28.08.2007 11:31:14 von PeterLarsen

Hi Walter,

A demo project has been sendt to your mail box.

/Peter

Re: ManualResetEvent / WaitOne

am 29.08.2007 13:24:54 von wawang

Hi Peter,

Thanks for the code.

Does the ManualResetEvent object is used to control synchronized access to
the UI controls? If that's the case, then I think you should probably use a
Mutex instead of an Event:

In your DoShellEvent, you called loaderLock.Reset(). Note this method will
not block, it merely set the Event's status to 'unlocked'. Instead, if you
created a Mutex and you replace this Event.Reset() with Mutex.WaitOne(),
the code will block if other thread (or the same thread) that already
acquired the lock. In your finally, you call Mutex.ReleaseMutex() to unlock
it.

I'm not sure why you're calling loaderLock.WaitOne() in the "CallMethod"
that's adding items to the listBox, could you please tell me about it? I
hope I haven't misunderstood anything.


Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Re: ManualResetEvent / WaitOne

am 30.08.2007 10:50:01 von PeterLarsen

Hi Walter,

Thanks for your comments.

The demo project just shows the easiest way to the problem.

In the application, where this behavior is a problem, the method
CallMethod() may be called from more than one threads.
If any thread want to prevent others from running CallMethod, they simply
signal that through loaderLock.

The following is very similar to what i do in the application:

if (loaderLock.WaitOne(0, true))
{
//do something if signaled
}
//otherwise just contintue (don't care)

CallMethod runs some checks and updates the datamodel accordng to the
result.
It doesn't matter whether two threads runs this method simultaneously or
not, i just want to prevent that the computer use all of its power in that
function.

Have you found why CallMethod is entered twice on shell events ??

BR
Peter

Re: ManualResetEvent / WaitOne

am 03.09.2007 10:40:12 von wawang

Hi Peter,

Sorry for delayed reply. I was not in office last Friday.

Back to the question, do you mean that the purpose of the ManualResetEvent
is to let any thread do operations, but don't let them block each other: as
long as there's some thread that is doing the operation, other threads can
continue working?

Not sure if this is related to the specific shell events, I think this can
be simulated by sending or posting some custom messages to the window and
trigger some action. I will do more test and get back to you.


Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Re: ManualResetEvent / WaitOne

am 04.09.2007 12:38:12 von wawang

Hi Peter,

I've done some test and found out that the WaitOne will do message loop if
its state is nonsignaled (just like calling Application.DoEvents, this will
cause other messages in the message queue to be processed before current
message is finished).

I will do some more research on this behavior.

In the meanwhile, could you please tell me more about your design?
Especially the purpose of the static ManualResetEvent, why you're resetting
it before calling the method; why you're setting it after the method?
Thanks.


Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Re: ManualResetEvent / WaitOne

am 04.09.2007 17:27:57 von PeterLarsen

Hi Walter,

You have got it right.
I want to let other threads to continue there jobs if one thread is already
doing the opration (in CallMethod).

BR
Peter

Re: ManualResetEvent / WaitOne

am 04.09.2007 17:51:07 von PeterLarsen

Hi Walter,

I don't understand why WaitOne cause (or allow) other messages to be
processed.
To me this behavior is against all i have learned about message queues
??!?!?!??

I have seen some similar behavior when using
SynchronizationContext.Current.Send(delegate {}, null);
And because of this i have given up using SynchronizationContext at the
moment and only use Invoke/BeginInvoke.

You ask about the ManuelResetEvent and why i do as i do - do you still have
questions about that ??

/Peter

Re: ManualResetEvent / WaitOne

am 05.09.2007 09:20:07 von wawang

Hi Peter,

Please refer to following blog:

#cbrumme's WebLog : Apartments and Pumping in the CLR
http://blogs.msdn.com/cbrumme/archive/2004/02/02/66219.aspx

It's a long article and talks about many advanced CLR stuff. You can search
for "WaitOne" to see the part related to our issue here (although I suggest
you to read them all for better understanding the whole issue). In summary,
the message pumping when you perform managed blocking (e.g.
WaitHandle.WaitOne) is a tradeoff to avoid deallocking; although this will
cause reentrancy.


Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Re: ManualResetEvent / WaitOne

am 05.11.2007 09:33:30 von PeterLarsen

Hi Walter,

I have read the blog now and it's very interesting stuff there.
I understand the garbage collector and the STA/MTA problems, but i still
think it should be possible to create some type of a special lock if i want
to.

The only way to solve this problem (not having/using locks) is to prevent
reentrancy by immediately return the second caller - and this only solve the
reentrance problem - the caller probably still need to call the method... !!

Regards
Peter

Re: ManualResetEvent / WaitOne

am 07.11.2007 04:32:36 von wawang

Hi Peter,

Thanks for your feedback. I understand your concerns here. You're welcome
to submit your feedback here
http://connect.microsoft.com/Main/content/content.aspx?Conte ntID=2220.


Regards,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.