Closure
Written by Mike James   
Tuesday, 11 May 2010
Article Index
Closure
Two patterns for closure
Event-oriented environment

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

.

Banner

 

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!

 

Banner


Deep C# - Casting the Escape from Strong Typing

Casting is one of the most confusing aspects of any modern language and it often makes beginners think hard. But if you know why you are doing it, then the how makes a lot more sense. We have encounte [ ... ]



Deep C# - Interface

Interfaces - what are they for? Not quite inheritance yet they seem to fit the same purpose. Find out in this extract from my new book, Deep C#: Dive Into Modern C#.


Other Articles

<ASIN:0470495995>

<ASIN:1430225254>

<ASIN:0596159838>

<ASIN:0672331012>

<ASIN:0470502266>

<ASIN:1430226536>



Last Updated ( Tuesday, 20 September 2016 )