<?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.配置项的大小写要注意。
把配置项<endpoint address="net.tcp://127.0.0.1:9999/CalculatorService
binding="netTcpbinding" contract="Artech.DuplexServices.Contracts.ICalculator"></endpoint>,红色部分没有注意大小写问题,导致了程序加载类异常。应该是binding="netTcpBinding"。
2.回调时不能关闭Tcp连接。
3.防止调用时的死锁。需要再契约上使用属性[OperationContract(IsOneWay=true)]。
源码地址:http://pan.baidu.com/s/1ntyP1ZN
框架图
原程序
Sevices
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:
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>