Sep 13, 2010

WCF Client side Aync Calls: Using BeginXXX EndXXX calls and use the ManualResetEvent for thread marshalling

Sample code:
1. Generate the Proxy with the /async switch
e.g.: svcutil.exe /serializer:DataContractSerializer /async /out:ServiceProxy.cs, "https://www.abcd.com/ServiceHost/UserManagement.svc"

2. Instantiate the proxy client:
e.g.:
UserManagementClient userClient = null;
endPtKey = "UserManagement_WindowsEndpoint";
userClient = new PartnerContactManagementClient(endPtKey);
User[] users = null;

3. Declare and Instantiate the manualresetEvents
e.g.:
ManualResetEvent[] handles = new ManualResetEvent[2];
handles[0] = new ManualResetEvent(false);
handles[1] = new ManualResetEvent(false);

4. Use the BeginXXX / EndXXX way of invoking aync calls:
(The following example is made using anonymous methods, so that we can use the local variables.)
e.g.:
AsyncCallback contactAsyncCallback = delegate(IAsyncResult userResult)
{
try
{
users = userClient.EndLookupUser userResult);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
finally
{
////Set the waithandle signal to true
handles[0].Set();
}
};

////The Begin Invoke Call
int userId = "12345";
contactClient.BeginLookupUser(userId, contactAsyncCallback, null);


5. Make the second such Async call:
e.g.:
UserRoles[] userRoles = null;

AsyncCallback roleAsyncCallback = delegate(IAsyncResult roleResult)
{
try
{
userRoles = userClient.EndLookupUserRoles(roleResult);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
finally
{
////Set the waithandle signal to true
handles[1].Set();
}
};

userClient.BeginLookupUserRole(userid, accountAsyncCallback, null);

6. Wait for the Calls to return:
e.g.:
WaitHandle.WaitAll(handles);
////At this point both the reset event would join back
////Close both the handles manually
handles[0].Close();
handles[1].Close();
////Write the follow up code