I have a WPF application which I'm currently working on separating into a client and server side - using WCF. I did not like the mess I initially got with the straight forward solution, so now I'm restructuring following the recommendations in the screencast of Miguel Castro, WCF Extreme. If you're not familiar with the video he basically sets up the whole communication manually - without using service references. This includes:
- A common Contract with all service and data contracts - referenced by the client and server
- A console application hosting the service
- Proxy classes on the client mapping up the service, and passing calls to it (using ClientBase or ClientFactory)
I've followed all his steps, and I really like where this is going. However, he does not address asynchronous service calls, and this is what I'd like to use.
When adding a Service Reference I can check a "Generate async operations" checkbox, and I get MyServiceCompleted and MyServiceAsync. However, I guess this is something which was generated when adding the service reference, and not some magic in the classes this builds on?
So, can I get async operations from ClientBase or ClientFactory somehow? Or do I have to define the actual server side services to be async? If so - could someone please give me a few hints or examples on how to get started with a simple async service? I've been reading around on MSDN on the subject, but it has left me all confused feeling like an idiot for not getting this already..
When you select "Generate async operations", as you noted, there is no magic involved:
Begin...
will start your communication, server starts processing stuff, but you can't use anything until you callEnd...
.All this behavior happens at client-side, so you don't need to change anything at your service implementation.
You're probably thinking this must be complex, but it don't ;)
EDIT: Here go an example:
You can also to explicitly program your service to work async, as describe here: Synchronous and Asynchronous Operations, by using
[OperationContract(AsyncPattern=true)]
An alternate way to achieve async operations on the client side without using the svcutil is to set up an interface (ServiceContract) locally on the client side which implements the async operation.
Contract on the server side:
Async contract on the client side
Note that the name and the default namespace needs to be set on the client contract in order to match the server contract's namespace. So now you have an async operation (without starting any new threads hopefully). This way you do not have to do any specific implementation on the server side. Off course this is similar to what the SvcUtil does but SvcUtil generates a lot of extra code and sometimes I find svcutil causing problems e.g. with the reuse of classes.
The ClientProxy
The usage of the client:
The server class
The server host
Implementing async operations on server side is quite simple. Make sure you method names match and are prefixed with Begin and End. GetImageAsyncResult is a custom IAsyncResult implementation (lots of examples on web).