<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="Artech.DuplexServices.Services.CalculatorService"> <endpoint address="net.tcp://127.0.0.1:9999/CalculatorService" binding="netTcpBinding" contract="Artech.DuplexServices.Contracts.ICalculator"></endpoint> </service> </services> </system.serviceModel> </configuration>
今天學習了WCF回調代碼,可能的異常,注意點。框架
1.配置項的大小寫要注意。tcp
把配置項<endpoint address="net.tcp://127.0.0.1:9999/CalculatorService
binding="netTcpbinding" contract="Artech.DuplexServices.Contracts.ICalculator"></endpoint>,紅色部分沒有注意大小寫問題,致使了程序加載類異常。應該是binding="netTcpBinding"。ide
2.回調時不能關閉Tcp鏈接。學習
3.防止調用時的死鎖。須要再契約上使用屬性[OperationContract(IsOneWay=true)]。spa
源碼地址:http://pan.baidu.com/s/1ntyP1ZN3d
框架圖code
原程序xml
Sevicesblog
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Artech.DuplexServices.Contracts; using System.ServiceModel; namespace Artech.DuplexServices.Services { public class CalculatorService : ICalculator { public void Add(double x, double y) { double result = x + y; ICallBack callback = OperationContext.Current.GetCallbackChannel<ICallBack>(); callback.DispalayResult(x, y, result); } } }
Contracts:ip
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace Artech.DuplexServices.Contracts { [ServiceContract(Namespace="http://www.artech.com/",CallbackContract=typeof(ICallBack))] public interface ICalculator { [OperationContract(IsOneWay=true)] void Add(double x, double y); } } namespace Artech.DuplexServices.Contracts { public interface ICallBack { [OperationContract(IsOneWay = true)] void DispalayResult(double x, double y, double result); } }
Hosting,
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Description; using Artech.DuplexServices.Contracts; using Artech.DuplexServices.Services; using System.ServiceModel.Channels; namespace Artech.DuplexServices.Hosting { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(CalculatorService))) { host.Open(); Console.Read(); } } } }
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="Artech.DuplexServices.Services.CalculatorService"> <endpoint address="net.tcp://127.0.0.1:9999/CalculatorService" binding="netTcpBinding" contract="Artech.DuplexServices.Contracts.ICalculator"></endpoint> </service> </services> </system.serviceModel> </configuration>
ClientConsole
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Artech.DuplexServices.Contracts; using System.ServiceModel; using System.ServiceModel.Channels; //system.serviceModel/bindings/netTcpbinding namespace Artech.DuplexServices.Clients { public class CalculateCallback : ICallBack { public void DispalayResult(double x, double y, double result) { Console.WriteLine("x+y={2} when x={0} and y={1}",x,y,result); } } } namespace Artech.DuplexServices.Clients { class Program { static void Main(string[] args) { InstanceContext instanceContext = new InstanceContext(new CalculateCallback()); using (DuplexChannelFactory<ICalculator> ChannelFactory = new DuplexChannelFactory<ICalculator>( instanceContext, "CalculatorService")) { ICalculator proxy = ChannelFactory.CreateChannel(); using (proxy as IDisposable) { proxy.Add(1,2); Console.ReadLine(); } } } } }
ClientConsole-AppConfig
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <endpoint name="CalculatorService" address="net.tcp://127.0.0.1:9999/CalculatorService" binding="netTcpBinding" contract="Artech.DuplexServices.Contracts.ICalculator"> </endpoint> </client> </system.serviceModel> </configuration>