我们知道web程序和服务器交互的经典模式就是一问一答,就是客户端向服务器发一个请求,然后等待请求的结果,客户端一直要等到接收到结果,才会继续执行。如果某个请求的计算需要比较长的时候,我们的页面就会假死状态,直到完全接收到结果。这个就是经典的”请求/应答模式”。
WCF中,默认情况下也是这种交互模式,但除了” 请求/应答”这种经典模式外,还有”单工操作”和”双工操作”两种模式,下面我们就简单地介绍一下WCF中这三个模式中的”单工操作”,再下一节演示”双工操作”,因为我自己也是初学者,所以示例会比较的简单,一为介绍,二为自己多熟练:
单向操作这种情况下,客户端不关心服务器是不是执行请求成功,也不会往客户端回发消息。所以想要实现这种操作的方法必须没有返回值,也就是返回值必须是void的方法,同样,服务器抛出的异常也不会传递到客户端。这种操作的好处就是,客户端发送请求后会马上继续执行后面的代码,不会停顿下来等待。
下面我们做一个简单的示例来演示一下单向操作:
先定一个契约:
[ServiceContract]
public
interface IOperate
{
[OperationContract]
void MyMethod();
}
这个契约中方法MyMethod没有标识为单向操作,那么它的交互模式就是”请求/应答”模式。
下面定义服务,实现这个契约:
public class Operate : IOperate
{
public void MyMethod()
{
Console.WriteLine("我被执行了,我要阻塞5秒钟!");
Thread.Sleep(5000);
}
}
服务中的MyMethod使线程挂起5秒。
然后是创建服务,为控制台程序:
class Program
{
static void Main(string[] args)
{
NetTcpBinding binding = new NetTcpBinding();
using (ServiceHost host = new ServiceHost(typeof(Operate)))
{
host.AddServiceEndpoint(typeof(IOperate), binding, "net.tcp://localhost:8001");
host.Opened += delegate
{
Console.WriteLine("wcf服务开启!");
};
host.Open();
Console.ReadLine();
}
}
}
接下面我们创建客户端(也是控制台程序)调用这个服务,因为是演示,所以使用简单的以编程的方式调用该服务:
class Program
{
static void Main(string[] args)
{
NetTcpBinding bind = new NetTcpBinding();
EndpointAddress address=new EndpointAddress("net.tcp://localhost:8001");
ChannelFactory<wcfservice.IOperate > clientfac = new ChannelFactory<wcfservice.IOperate >(bind, address);
clientfac.Open();
wcfservice.IOperate clientproxy = clientfac.CreateChannel();
Console.WriteLine("将要执行wcf服务:" + DateTime.Now);
clientproxy.MyMethod();
Console.WriteLine("wcf服务执行完了:" + DateTime.Now);
clientfac.Close();
Console.ReadLine();
}
}
接下来我们就是看看演示的效果了,先运行服务,运行窗口如下:
图1
然后我们运行客户端,运行窗口如下:
图2
从上面的运行结果看,客户端被阻塞了5秒钟,这是因为经典的” 请求/应答”模式客户端需要等待服务器的结果才会执行下面的代码。
下面我们将契约修改如下:
[ServiceContract]
public interface IOperate
{
[OperationContract(IsOneWay = true)]
void MyMethod();
}
注意:
IsOneWay = true就标识了方式MyMethod为单向操作,不需要其它任何额外的代码就能实现单向操作了。示例中的其它代码都不变化,现在看看单向操作的效果。
还是先运行服务,运行窗口如下,和图1是一样的,没有任何区别:
图3
再运行客户端,运行窗口如下:
图4
这上面的运行可以看到,客户端在调用服务中MyMethod()方法后立刻执行了后面的代码,并没有等待5秒,这个就是单向操作的效果了。