EndInvokeCalled

  • Thread starter Thread starter marvind
  • Start date Start date
M

marvind

I came across the following sample code:

while (!ar.EndInvokeCalled)
{
// If you comment out the line below, the loop will not work
// because you have to let the Form process events in the message
queue
Application.DoEvents();
}

I am not using Forms and a tight loop still does not work. Why is that?


What is the correct way to check this property in the parent thread?
Please note that I am not trying to eliminate the busy wait code.

Thanks
 
marvind,

It seems like you are waiting for your asynchronous operation to
complete. Instead of polling like that, why not just pass a callback to
your call to BeginInvoke, which is called when the operation is complete?
Then, you can complete your operation from there.

Hope this helps.
 
Yes, in fact, I pass a callback and have made the call to EndInvoke the
very last piece of code in the callback (I do not need results). Still
I have the situation that the parent thread cannot exit after spawning
the threads and it has nothing else to do, so the parent thread waits
until timeout and then signals currently spawned threads to exit (by
setting a boolean variable to true that is checked by spawned threads)
and then waits for them to exit by polling EndInvokeCalled for each
currently spawned thread. When EndInvokeCalled is true for all
currently executing threads, the parent thread exits.

I am not sure if I have used the best design but here are my thoughts:
1. I wanted to spawn an initial set of threads one on each server in
the parent and then have the spawned threads finish their work and
start a new one async on the same server and then exit
2. I wanted a realiable way to know if the threads had finished. Apart
from using other signaling mechanisms like ManualResetEvent or
semaphores, I could only think of the EndInvokeCalled property.
2. End
 
marvind,

You should call EndInvoke at the start of the callback, even if you
don't need the results. The reason for this is that EndInvoke will
(ultimately) release the mutex that is associated with the implmentation of
IAsyncResult. Right now, it doesn't, but it should be fixed at a later date
(the CLR team knows about this, and it is slated for fixing in the next
version of .NET beyond 2.0). This will make your code more tolerant for
future changes.

That being said, if you have access to the IAsyncResult implementation,
instead of polling for EndInvokeCalled, why not just wait on the
AsyncWaitHandle that is exposed? If you are doing this in a UI thread, then
you can spawn a new thread which will wait on all of the callbacks.

Or, you could have a single callback method which is the callback for
all of the methods you call. You then keep a list of the asycnhronous
operations somewhere which you remove from the list when the operation is
complete.
 
marvind said:
I came across the following sample code:

while (!ar.EndInvokeCalled)
{
// If you comment out the line below, the loop will not work
// because you have to let the Form process events in the message
queue
Application.DoEvents();
}

I am not using Forms and a tight loop still does not work. Why is that?


What is the correct way to check this property in the parent thread?
Please note that I am not trying to eliminate the busy wait code.

Thanks

a tight loop still does not work.....What exactly do you mean by this? Maybe
you should post some repro code.

Anyway, you should not call DoEvents() either, if there is no message loop
(no UI thread) this results in a NOP.

Willy.
 
Yes, I cannot call Application.DoEvents since it is not a UI thread. If I
have this tight loop (with call to DoEvents() commented out) then the thread
never exits the loop. If I add a bogus function DoSomeStuff() and put a wait
in that then the EndInvokeCalled property is updated. I did not know what was
happening (still do not) when I came across this article below (scroll to the
end or search for DoEvents):

http://www.knowdotnet.com/articles/delegates-printable.html
 
Back
Top