I’m trying to implement a WCF service as a Windows service. I’d like to call it asynchronously as there are some methods that may potentially run for a couple of seconds. Following misc. tutorials (e.g. from the MSDN) didn’t really seem to do the job. I’ve got some bits working, but the data returned from the service to the client is not what I expect. Example code for the service on the server is as follows:
public interface ISomeService
{
[OperationContract(AsyncPattern = true)]
IAsnycResult BeginSomeMethod(string someString);
Collection<string> EndSomeMethod(IAsnycResult asyncresult);
}
[...]
public SomeService : ISomeService
{
public IAsyncResult BeginSomeMethod(AsyncCallback callback, object state)
{
// Do something...
Collection collection = new Collection<string>{"Some Item", "Another Item"};
return new CompletedAsyncResult<Collection<string>>(collection);
}
public Collection<string> EndSomeMethod(IAsyncResult asyncResult)
{
CompletedAsyncResult<Collection<string>> result =
asyncResult as CompletedAsyncResult<Collection<string>>;
if(result != null)
{
return result.Data;
}
return result;
}
}
I can successfully install the Windows service and also call it via the browser to see the WSDL. I can also add a reference to my “client” project to consume it – proxy classes etc. are generated without any errors. I can also call my methods like this:
[...]
object async = new object();
someService.BeginSomeMethod( "Some string", EndSomeMethod, async );
[...]
The callback method looks like this:
[...]
public static void EndSomeMethod( IAsyncResult asyncResult )
CompletedAsnycResult<Collection<string>> result =
asyncResult as CompletedAsnycResult<Collection<string>>;
[...]
Following this, result is null (i.e. the cast was not successful), and asyncResult does contain some properties and data, but not the expected (or wanted) string collection.
Edit
I can verify that the service method does what it is supposed to do (e.g. write to a log file, create a file or similar stuff).
/Edit
I’ve tried a couple of more approaches, but I’m somewhat confused as to what I’m doing wrong here. The examples available from Microsoft are apparently not correct (as read on some of the MSDN pages). I also found some other suggestions with event handlers etc., but was it the best way to go now?
Do I actually have to decorate service methods with the AsyncPattern = true in the OperationContract attribute? Or can I just use VS2010’s facility to generate methods for asynchronously calling the methods?
I know that there are numerous questions regarding this issue, but after spending hours on this issue I feel quite stuck.
You need to call
someService.EndSomeMethod(asyncResult)in your callback to get the service result. This is actually part of the standard APM pattern. You’d have to do the same thing with say aFileStream.Yes, because
CompletedAsnycResultonly exists on the server. Your client can get any other type returned by the runtime. IAsyncResult is not part of the WCF wire-contract.In practice,
asyncResultwill be an instance of some WCF-internal class.