UCMA 2.0 - Part 1.2 - Asynchronous pattern and threading model
Before you really start coding in UCMA 2.0, or even UCMA 1.0, it is extremely important that you understand the asynchronous pattern. UCMA is designed for server applications, meaning it supports many operations occurring at the same time. In order to best manage this, it uses an asynchronous model.
For instance, let’s begin by discussing one of the most important classes in UCMA 2.0, CollaborationPlatform. After you have created an instance of this class, you will need to start it. The method to start CollaborationPlatform is not called ‘Startup’, but is instead called BeginStartup. The method signature is the following.
IAsyncResult BeginStartup(AsyncCallback userCallback, object state)
The key thing to remember with asynchronous APIs, is that BeginStartup will return almost immediately after being called. The actual work will be accomplished in another thread. So how can you tell when it is completed? There are two ways to accomplish this.
1) Using the IAsyncResult object returned from BeginStartup. For the best description, look this object up in MSDN, but in summary it provides a wait handle that you can wait on and an IsCompleted property. Of course, waiting on either of these will block your thread, which is probably not what you would like to do.
2) The other way is to receive the callback in the AsyncCallback method you provide. When the operation has finished, UCMA will call this method.
To enable the same AsyncCallback method to work for several different method calls, you can pass any object as the state parameter. When UCMA calls you back, it will send you this object. The AsyncCallback delegate requires a method that takes a single parameter – IAsyncResult. Within the IAsyncResult object passed back, you can retrieve the state variable from the AsyncState property.
So what do you do when you are called back? In general, you are going to want to know what happened. Did CollaborationPlatform start up correctly? To accomplish this, you will call the Endxxx form of the method. So in this case you will call EndStartup. EndStartup has the following signature.
void EndStartup(IAsyncResult result)
OK, so this one isn’t very exciting. There is no start returned, but to ensure that resources are no longer consumed, you should always call the appropriate Endxxx method in the callback from the Beginxxx method. Let’s look at a more interesting Endxxx method – EndEstablish in ApplicationEndpoint.
SipResponseData EndEstablish(IAsyncResult result)
The SipResponseData object returned will contain information on whether we managed to establish the endpoint. Of course, for simplicity sake, you could make the following call.
SipResponseData data = endpoint.EndEstablish(endpoint.BeginEstablish());
Within these blogs, I will make use of this sometimes. The main reason I will use it is I will be showing Powershell commandlets written with UCMA. As Powershell commandlets are synchronous, it makes sense to use this at times. However, you should not use this when writing server applications. When I switch from discussing signaling to the collaboration API, I will switch to using the callback.
Now that you understand the asynchronous pattern better, let’s take a look at the Signaling API.