Showing posts with label Asynchronous. Show all posts
Showing posts with label Asynchronous. Show all posts

Simultaneously Calling Several Asynchronous Web Service Methods

Saturday, November 10, 2007

It's no more a secret that web services have become extremely popular past couple of years. Many distributed applications contain web services as a part of the solution. Even if your solution does not need a web service, you may need to consume a third party web service at some point.

C#/.NET makes it easy both creating your own web service and consuming either your own or a third party web service. As you may already know, you can call web service methods either synchronously or asynchronously. Frequently, asynchronous method of calling web service methods is a preferred way. Generally, when possible, I do use asynchronous calls.

Currently, I'm working on a project that heavily uses web services. At one point I ran in a situation where I needed to call multiple web service methods simulatenously. Development of the web service and the consumer application goes in parallel. Naturally, before consuming a web service method, we do test the web service. Suddenly, a strange exception started occurring when we were asynchronously calling two web service methods at the same time. The exception message is given below and you can see it in the screen shot.


Exception has been thrown by the target of an invocation.

InnerException

"There was an error during asynchronous processing. Unique state object is required for multiple asynchronous simultaneous operations to be outstanding."

When I checked the web service methods, they both worked without any problems.

It looks like that when we call several web service methods asynchronously, we need to somehow differentiate the calls. If you provide unique UserState objects to the calls, then this exception does not occur. But what shall we do if we do not need to use UserState objects at all? I have simply solved this by supplying a dummy user state object.

Look at the code fragment below. m_WSController is the instance of the web service class. Here I call two methods asynchronously:

GetPaymentMethodsAsync and GetUserPaymentDetailsAsync. Notice that adding a simple new object() dummy user state object solves the problem.

// THIS DOES NOT WORK

m_WSController = new MyApp.WebService.Controller();

m_WSController.GetUserPaymentDetailsCompleted += new MyApp.WebService.GetUserPaymentDetailsCompletedEventHandler(m_WSController_GetUserPaymentDetailsCompleted);
m_WSController.GetPaymentMethodsCompleted += new MyApp.WebService.GetPaymentMethodsCompletedEventHandler(m_WSController_GetPaymentMethodsCompleted);

m_WSController.GetPaymentMethodsAsync();
m_WSController.GetUserPaymentDetailsAsync(m_SessionId);

// THIS WORKS!


m_WSController = new MyApp.WebService.Controller();

m_WSController.GetUserPaymentDetailsCompleted += new MyApp.WebService.GetUserPaymentDetailsCompletedEventHandler(m_WSController_GetUserPaymentDetailsCompleted);
m_WSController.GetPaymentMethodsCompleted += new MyApp.WebService.GetPaymentMethodsCompletedEventHandler(m_WSController_GetPaymentMethodsCompleted);

m_WSController.GetPaymentMethodsAsync(new object());
m_WSController.GetUserPaymentDetailsAsync(m_SessionId);


Hopefully, this saves you time when getting the above described exception.