Re: Async callback vs events vs ?
- From: Jonathan <blank@xxxxxxxxxxx>
- Date: Wed, 15 Jul 2009 08:27:38 +0100
Peter Duniho wrote:
On Tue, 14 Jul 2009 01:09:34 -0700, Jonathan <blank@xxxxxxxxxxx> wrote:Pete,
[...]
I suppose I could use the IAsyncResult to pack this information in but - and here is where I lose the plot - all of this is still running under the thread from the threadpool as far as i can tell. This seems to make life complicated and dangerous since there is still a lot I need to do with the information returned including updating the GUI, calling more methods, ...
How do I escape from this situation?
Define "escape". If by that you mean "avoid it altogether", you can't without abandoning the idea of asynchronous processing altogether itself. Asynchronous necessarily implies a thread other than your main GUI thread; updating the GUI from some other thread necessarily implies using Control.Invoke() or Control.BeginInvoke() to execute code that actually updates the GUI.
The main thing when calling Control.Invoke() or Control.BeginInvoke() is to make sure you aren't capturing variables in anonymous methods that may change in the course of the threading. But even there, assuming those variables are used only in the one async thread, then calling Control.Invoke() will ensure that, because it blocks until the delegate has actually been invoked; that thread _can't_ change the values, even if they happen to be non-local, because the thread's just waiting for the GUI to finish being updated.
With Control.BeginInvoke() you need to be more careful, but that mainly means copying values from non-local variables into captured local variables that you know won't be changed anywhere in that method.
That said, the code you posted looks mostly workable. The only thing you probably need to really fix is the lack of a call to Control.Invoke() in your event handler ("MyLogic_LogicEvent"). I would expect everything else to run fine as-is.
Which is not to say it's how I'd write it myself. :) Other changes I'd make:
-- Don't bother with the System.Runtime.Remoting.Messaging.AsyncResult class. IAsyncResult provides everything you need; just pass your delegate instance as the state object to the call to BeginInvoke(), and then retrieve that from the IAsyncResult.AsyncState property.
-- Related to the above, there's no need to check the EndInvokeCalled property; your callback will only be called once per invocation, and you should write the code to only call EndInvoke() in that callback. Thus, EndInvokeCalled will (should) always be "false".
-- Also, there's no need to check InvokeRequired. It's a legacy property that really has no need any longer (and barely had a need in the past). The call to Control.Invoke() does the exact same check, and will simply invoke the delegate directly if InvokeRequired is false. There's practically no additional overhead even if it does sometimes happen that InvokeRequired might be "false", and of course in this case that's just not going to happen anyway.
But note that those changes are all mostly stylistic; they have little bearing on the _correctness_ of the code.
I hope this makes sense to you - feel free to put me straight on the concepts I am obviously floundering with :)
For someone who's floundering, you sure seem to already understand pretty much everything that's going on. :)
Pete
Much obliged again for your thoughts and thanks for your reassurance!
I don't have anyone to bounce off at work for C# stuff and it's sometimes difficult - even when you think you know something - to be completely sure that you are correct in your understanding.
Re the event handler:
I left the event handler code as it was since I anticipated abandoning this mechanism in favour of callbacks. I read an anecdote somewhere (sorry, cannot cite this) that got me a little worried:
"this is not the only important point I disagree with in that article. For example, I think that it's almost always going to be a bad idea to use asynchronous delegate invocation to raise events. This would be a total disaster if you ever used the event source in a Windows Forms application, for example."
If this is a red herring and there are really no issues with such a mechanism, I'll follow your recommendation for this.
Your other observations are very useful - I kind of "get it" now regarding what's going on in the background which is important to see *why* things need to be done the way they do...
Thanks again!
Regards
Jon
.
- Follow-Ups:
- Re: Async callback vs events vs ?
- From: Peter Duniho
- Re: Async callback vs events vs ?
- References:
- Async callback vs events vs ?
- From: Jonathan
- Re: Async callback vs events vs ?
- From: Peter Duniho
- Re: Async callback vs events vs ?
- From: Jonathan
- Re: Async callback vs events vs ?
- From: Peter Duniho
- Async callback vs events vs ?
- Prev by Date: Re: Something is wrong with my data marshaling
- Next by Date: Re: Async callback vs events vs ?
- Previous by thread: Re: Async callback vs events vs ?
- Next by thread: Re: Async callback vs events vs ?
- Index(es):
Relevant Pages
|