When a server is published, the client can generate the corresponding code by adding the service reference in VS2010 with the metadata of the server. And you can choose to generate the appropriate asynchronous operation.
The WCF implementation code, the add operation delays 5 seconds before returning the result.
[ServiceContract] Public InterfaceICalculator {[OperationContract]intADD (intXinty); } [ServiceBehavior] Public classCal:icalculator { Public intADD (intXinty) {System.Threading.Thread.Sleep ( the); returnX +y; } }
Service Homestay:
Static voidMain (string[] args) {ServiceHost host=NewServiceHost (typeof(KK. Cal)); ServiceMetadataBehavior Behavior=NewServiceMetadataBehavior (); Behavior. Httpgeturl=NewUri ("Http://localhost:6666/meta"); Behavior. Httpgetenabled=true; Host. DESCRIPTION.BEHAVIORS.ADD (behavior); Host. AddServiceEndpoint (typeof(KK. ICalculator),NewWshttpbinding (),"http://localhost:6666"); Host. Opened+=Delegate{Console.WriteLine ("Service start!");}; Host. Open (); Console.ReadLine (); }
The service's metadata address can be set through ServiceMetadataBehavior's Httpgeturl, where the client obtains all the information about the service.
Run the service side first. Then follow these steps to add a service reference to the client
1. Add a service Reference
2. Enter the metadata address for the service advertisement.
3. Create an asynchronous operation in the advanced Select. Then click on 2 to go.
First, the client is invoked through the Beginadd/endbegin method.
After the build succeeds, it gets to the client through the default namespace ServiceReference1, calling the BeginAdd method directly to make an asynchronous call.
Static voidMain (string[] args) {servicereference1.calculatorclient Client=Newservicereference1.calculatorclient (); Client. BeginAdd (1,2, CallBack, client); for(inti =0; I < -; i++) {System.Threading.Thread.Sleep ( +); Console.WriteLine ("{0}", i); } } Public Static voidCallBack (IAsyncResult ar) {servicereference1.calculatorclient client= Ar. AsyncState asservicereference1.calculatorclient; intresult =client. EndAdd (AR); Console.WriteLine ("result:{0}", result); }
The first two parameters of a beginadd are contract interface parameters. The third is the callback method, with the parameter type IAsyncResult a delegate with a return value of void. The fourth is the object class, where client clients are passed in because the EndAdd method needs to be called in the callback method to get the result. Or simply define the client as a static member variable so that it does not need to be passed in.
Second, add the delegate through xxxcompleted.
Static voidMain (string[] args) {servicereference1.calculatorclient Client=Newservicereference1.calculatorclient (); Client. Addcompleted+=Delegate(Objectsender, Servicereference1.addcompletedeventargs e) { int[] para = e.userstate as int[]; intresult =E.result; Console.WriteLine ("result:{0}+{1}={2}", para[0], para[1], result); }; Client. Addasync (1,2,New int[]{1,2}); for(inti =0; I < -; i++) {System.Threading.Thread.Sleep ( +); Console.WriteLine ("{0}", i); } }
The completed+= delegate is a variant above that gets the result directly from the CompletedEventArgs result property, userstate gets additional parameters.
The two implementations of the above asynchronous invocations are:
By observing the code generated by the client by adding a service reference,
public partial class Calculatorclient:system.servicemodel.clientbase<client2. Servicereference1.icalculator>, Client2. Servicereference1.icalculator
Discover that Servicereference1.calculatorclient is inherited from
Public abstract class Clientbase<tchannel>: Icommunicationobject, IDisposable where Tchannel:class
This also means that we can customize a cinent without having to generate a lot of useless code.
usingSystem.ServiceModel;usingSystem.ServiceModel.Channels;namespaceclient2{classProgram {Static voidMain (string[] args) {myclient Client=NewMyClient (NewWshttpbinding (),NewEndpointAddress (NewUri ("http://localhost:6666"))); intResult=client.mychannel.add (1,2); Console.WriteLine ("{0}", result); } } Public classMyclient:clientbase<kk. Icalculator> { Publicmyclient (Binding bind, EndpointAddress addr):Base(bind, addr) {} PublicKK. ICalculator MyChannel {Get { return This. Channel; } } }}
MyClient inherits ClientBase and specifies generic contracts, overriding base class constructors, specifying binding and EndpointAddress. And by returning the base class channel property. Constructs the binding mode used by the incoming server, and the endpoint address. The channel can then be obtained through MyChannel. In fact, this clientbase internal is also through the channelfactory<t> implementation, through the channel factory to create channels, through the channel Call server method. The following code is implemented through a channel factory.
Static void Main (string[] args) { ChannelFactorynew Channelfactory<kk. Icalculator> (newnew endpointaddress (thenew Uri ("http://localhost:6666 "))); Kk. ICalculator MyChannel=factory. CreateChannel (); MyChannel. ADD (12); }
wcf-asynchronous invocation and two client forms