wcf异步编程
契约:
using System; using System.ServiceModel; namespace WcfAsync { [ServiceContract] public interface ICalculatorService { [OperationContract(AsyncPattern = true)] IAsyncResult BeginAdd(decimal x,decimal y,AsyncCallback callback,object state); decimal EndAdd(IAsyncResult ar); } }
实现:
using System; using System.Threading; namespace WcfAsync { public class CalculatorService:ICalculatorService { public IAsyncResult BeginAdd(decimal x, decimal y, AsyncCallback callback, object state) { AsyncResult ar = new AsyncResult(x, y, callback, null); return ar; } public decimal EndAdd(IAsyncResult ar) { AsyncResult ret = ar as AsyncResult; if (ret!=null) { return ret.Add(); } return 0; } } public class AsyncResult:IAsyncResult { private decimal _x; private decimal _y; private AsyncCallback _callback; private ManualResetEvent _waitHandle; private object _asyncState; private bool _isCompleted; public AsyncResult(decimal x, decimal y, AsyncCallback callback, object state) { _x = x; _y = y; _callback = callback; _asyncState = state; _waitHandle=new ManualResetEvent(false); } public object AsyncState { get { return _asyncState; } } public System.Threading.WaitHandle AsyncWaitHandle { get { return _waitHandle; } } public bool CompletedSynchronously { get { return true; } } public bool IsCompleted { get { return _isCompleted; } private set { _isCompleted = value; } } public decimal Add() { Thread.Sleep(6000); _waitHandle.Set(); IsCompleted = true; _callback(this); return _x + _y; } } }
主机:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="svcBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:9999/CalculatorService/Metadata"/> </behavior> </serviceBehaviors> </behaviors> <bindings> <wsHttpBinding> <binding name="wsHttpBinding" textEncoding="UTF-8"></binding> </wsHttpBinding> </bindings> <services> <service name="WcfAsync.CalculatorService" behaviorConfiguration="svcBehavior"> <endpoint address="http://localhost/CalculatorService" binding="wsHttpBinding" contract="WcfAsync.ICalculatorService"> </endpoint> </service> </services> </system.serviceModel> </configuration>
using System; using System.ServiceModel; using WcfAsync; namespace Host { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(CalculatorService))) { host.Open(); Console.Read(); } } } }
客户端:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="wsHttpBinding" textEncoding="utf-8" /> <binding name="WSHttpBinding_ICalculatorService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Message"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" /> <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" /> </security> </binding> </wsHttpBinding> </bindings> <client> <endpoint address="http://localhost/CalculatorService" binding="wsHttpBinding" contract="WcfAsync.ICalculatorService" name="calculator" /> <endpoint address="http://localhost/CalculatorService" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculatorService" contract="ServiceReference.ICalculatorService" name="WSHttpBinding_ICalculatorService"> <identity> <userPrincipalName value="ZHOULQ\Administrator" /> </identity> </endpoint> </client> </system.serviceModel> </configuration>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.Threading; //using Client.ServiceReference; using WcfAsync; namespace Client { class Program { static void Main(string[] args) { using (ChannelFactory<ICalculatorService> fac = new ChannelFactory<ICalculatorService>("calculator")) { ICalculatorService calc = fac.CreateChannel(); IAsyncResult ar=calc.BeginAdd(3,7,null,null); Console.WriteLine("Start......"); Console.WriteLine("Wait......"); decimal ret=calc.EndAdd(ar); Console.WriteLine("Result is {0}",ret); Console.WriteLine("End......"); } Console.Read(); //ServiceReference.CalculatorServiceClient c=new CalculatorServiceClient(); //Console.WriteLine(c.Add(3,4)); //Console.Read(); } } }