I'm consuming a third-party resource (a .dll) in a web service, and my problem is, that invoking this resource (calling a method) is done asynchronous - I need to subscribe to an event, to get the answer for my request. How do I do that in a c# web service?
From MSDN docs:
using System;
using System.Web.Services;
[WebService(Namespace="http://www.contoso.com/")]
public class MyService : WebService {
public RemoteService remoteService;
public MyService() {
// Create a new instance of proxy class for
// the XML Web service to be called.
remoteService = new RemoteService();
}
// Define the Begin method.
[WebMethod]
public IAsyncResult BeginGetAuthorRoyalties(String Author,
AsyncCallback callback, object asyncState) {
// Begin asynchronous communictation with a different XML Web
// service.
return remoteService.BeginReturnedStronglyTypedDS(Author,
callback,asyncState);
}
// Define the End method.
[WebMethod]
public AuthorRoyalties EndGetAuthorRoyalties(IAsyncResult
asyncResult) {
// Return the asynchronous result from the other XML Web service.
return remoteService.EndReturnedStronglyTypedDS(asyncResult);
}
}
Assuming your 3rd party component is using the asynchronous programming model pattern used throughout the .NET Framework you could do something like this
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.stackoverflow.com");
IAsyncResult asyncResult = httpWebRequest.BeginGetResponse(null, null);
asyncResult.AsyncWaitHandle.WaitOne();
using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.EndGetResponse(asyncResult))
using (StreamReader responseStreamReader = new StreamReader(httpWebResponse.GetResponseStream()))
{
string responseText = responseStreamReader.ReadToEnd();
}
Since you need your web service operation to block you should use the IAsyncResult.AsyncWaitHandle instead of the callback to block until the operation is complete.
If the 3rd party component does not support the standard asynchronous programming model (i.e it does not use IAsyncResult), you can still achieve synchronization using AutoResetEvent or ManualResetEvent. To do this, declare a field of type AutoResetEvent in your web service class:
AutoResetEvent processingCompleteEvent = new AutoResetEvent();
Then wait for the event to be signaled after calling the 3rd party component
// call 3rd party component
processingCompleteEvent.WaitOne()
And in the callback event handler signal the event to let the waiting thread continue execution:
processingCompleteEvent.Set()