|
Page 3 of 3
Using closure 2 - the Event pattern
There is one very important situation where closure simplifies things - although not everyone agrees that it is a good idea. In an event oriented environment the linear flow of actions is often made unclear by the need to pause processing until an event occurs. Situations like this occur all the time but to make the explanation easier to follow let's try to remain general
.
Suppose you are writing some code that works with some resources and you get to the point where you need to load a new resource and this is a time consuming action then there are two approaches blocking synchronous and non-blocking asynchronous. Blocking synchronous simply causes the thread doing the work to pause until the resource is loaded:
work with resources request new resource wait(until resource loaded) continue with processing
This has the avantage of simplicity and you can clearly see what is happening but if the processing thread is also processing events then all event handling stops at the wait. This is a common problem that can be partly elieviated by use of constructs such as DoEvents which sends the thread off to process events while waiting:
work with resources request new resource Do Until (resource loaded) DoEvents Loop continue with processing
This approach has many problems - the biggest being re-entrancy i.e. what if an even that occurs as the result of DoEvents restarts the entire method over again.
The second approach, non-blocking asynchronous, is to use an event to trigger the resumption of the processing when the resource has loaded. For example,
work with resources setup resource loaded event handler request new resource end method
When the method ends the thread can continue to process events and when the resource is loaded the assigned event handler is invoked and processing continues,
The problem with this is that the event handler has to be written else where and its self contained and doesn't share access to any of the resources of the original processing method. That is the logic of the program says:
do actions A load new resource do actions B end AB
and A and B are linked in the sense that B might well need access to variables that were created as part of A but the need not to block the thread waiting for the resource load mean this has to be written as:
do actions A set B to be onload event handler load new resource end A
onload Do B end B
Not only is the flow of control confused by this break but B doesn't have access to the variables etc in the scope of A.
At this point you should be thinking - closure.
If the event handler is defined as an anonymous method in the scope of A then when it runs, whenever that might be it has access to the original environment provided by A. That is:
do actions A set B to be onload event handler load new resource
onload anonymous method Do B end B end A
Now not only is it clear that the flow of control is do A then do B but B has access all of the variables defined in A and can continue the processing as if it hadn't had to wait for an event.
If you would like to see a practical example of this in action then see Loading Bitmaps: DoEvents and the closure pattern.
The use of closure to make non-blocking asynchronous coding look more like blocking synchronous coding is one of the big advantages of using a closure - but don't over use it!
Getting started with C# Metro apps
How does Metro development in C# differ from desktop development? After looking at some general differences and the overall structure of a Metro app, we move on to consider how to make use of asynchro [ ... ]
|
How to number crunch - NAG for .NET
Number crunching in C# (or any .NET language) is a problem because it doesn't have a long tradition of implementing numerical methods. So why not use a library that was originally implemented in Fortr [ ... ]
| | Other Articles |
<ASIN:0470495995>
<ASIN:1430225254>
<ASIN:0596159838>
<ASIN:0672331012>
<ASIN:0470502266>
<ASIN:1430226536>
|