<?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

框架图

WCF回调操作-LMLPHP

原程序

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(,);
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>
05-26 12:38