Our own local Delta representative, Venkat Polisetti kicked the meeting off with a presentation about web services on the Compact Framework. To begin, we compared synchronous web calls to asynchronous web calls:
Synchronous calls to web services:
- can be dangerous because they have the possibility to freeze your user interface until the call completes in the primary thread.
- can be useful when the web method returns quickly and they are very easy to code.
Asynchronous calls are:
- executed on a different thread
- more complex to code but
- won’t freeze your UI when the web methods are slow to respond.
Consuming a web services on the Compact Framework is pretty much the same as with web and winform apps. When a web reference is added to a project, VS.Net creates a proxy class in the project and creates Begin and End methods for asynchronous operations. Call the Begin method to initiate the web service call and call the End method to complete the web service call. Venkat had prepared a demo for us to help us understand the complexities of using web services and the Compact Framework but his demo misbehaved a bit; the group tried to help out but the problems were initially beyond us. So Venkat took a seat to work on his laptop and gave the floor to Dhamayanthi (D for short). We ran out of time, so Venkat will show off his demo at the next Mobility UG meeting (he did get things working before the end of D’s presentation)
D started her presentation with a quick recap of polymorphism and inheritance. The example she gave was to create a base class with multiple layers of inheritance – ProjectManager inherits from Employee which inherits from Person. She then posed a question to the group, “How do you create the correct object when you don’t know which type of object is required up-front?” The answer is to have the code look up the correct object type and then return to the calling function a reference of type MyAbstractBaseClass. The reference will point to the correctly created object type. This explanation of an Object Factory also encapsulates the concept of dynamic polymorphism. We had spiraled out to a discussion of the Abstract Factory design pattern before D reigned us in and brought us back to dynamic polymorphism with an explanation of how delegates help simplify function calls which have the same signature. She showed us how to use a delegate in C++ before showing us the differences in C#, making sure we all knew our roots.
A delegate in C# is an object-oriented, type safe function pointer. This complicated concept is easily explained by Chris Sell’s article, “.Net Delegates: A C# Bedtime Story”. The story tells of an employee with a mean boss. The employee writes code to notify his boss every time his status changes and the boss is happy. But the next day the boss’s boss wants to be notified of the employee’s status changes. This continues (adding bosses to the list) until the employee is forced to allow any interested party to subscribe to his status change events. To do this, the employee defines an interface that the various bosses will implement (thus inheriting from the employee’s class (Interface Inheritance)). Now anyone who implements the interface can pass their own objects into the interface methods as parameters. This demonstrates polymorphism b/c the functions don’t know ahead of time which objects (bosses) are going to ask for status updates but they are able to take any objects that implement the interface.
The next step in improving the code is to allow the boss objects to implement only the interface methods that they are interested in, not the ones they don’t care about. The other thing we can improve upon is not requiring the use of specific method names. Delegates are interfaces with one method which don’t require interface inheritance. This is good b/c in .Net we are only able to derive from a single base class. By taking each method in an interface and declaring them each as an individual delegate (essentially wrapping the method call in a delegate) the coupling is much looser – improving the flexibility of the code. Delegates are capable of wrapping both instance methods (created when you new up an object) and static methods (which don’t require the creation of an object).
A problem of delegates is that they are public methods and can be directly invoked (skipping the notification feature of the delegate). Another problem of delegates is that a delegate only returns to the last registrant. If multiple people register for the event and they don’t register for an event with +=, then they will erase all the other registrations. To prevent this, wrap the delegates in events. The framework will then create the register and unregister events. If someone then tries to use the event without using += syntax they get a compiler warning. D was on the ball tonight, even breaking out ILDASM to show us what was happening under the covers with delegates and events, and how += completed and -= completed are both overloaded in IL as add_completed and remove_completed (where completed is our delegate name).
The next problem we had to solve was how to get the return value of each delegate or event call when multiple objects (bosses) have registered. The answer is to use the event’s .GetInvocationList method and save the results in a delegate variable. Of course, we don’t want to do this synchronously – we need to make sure we can pass by registrants who aren’t ready to report their results. This is where the BeginInvoke method of a delegate comes into play – you can call the event’s BeginInvoke on the method without passing anything in or retrieving anything out. This is the Fire and Forget method of handling this problem. A better way to handle this problem is to use the IAsynchResult interface and the callback functionality (which takes advantage of the threadpool). The IAsynchResult interface exposes an IsCompleted method which can be used to poll a thread’s status. Once IsCompleted = TRUE, you can call the event’s EndInvoke method. However, EndInvoke is a blocking call so you don’t want to call it unless you’re sure that job is done. The most elegant method of handling the check of return results is to define an AsynchDelegate (type AsynchCallback) to do the checking for you.
A great question was asked by the group – what happens if the event you are calling on a different thread throws an exception? How do you inform your main thread? This question is left as an exercise for the reader! We didn’t have time in the group to really explore the issue.
Positive feedback all around – everyone though the topic was fantastic and that D was a great presenter. In fact, if she ever comes back to Atlanta, we’d love to have her back to present another topic. She told us she’s got a great presentation on design patterns. Maybe I’ll be able to get this presentation from her and let the group work with it on their own time.
Thank you to everyone who showed up and thank you to both Venkat and Dhamayanthi for presenting!
— Matt Ranlett
posted with BlogJet