当发布一个服务端之后,客户端可以通过服务端的元数据,用VS2010添加服务引用的方式生成对应的代码。并且可以选择生成相应的异步操作。

WCF实现代码,Add操作延时5秒后再返回结果。

[ServiceContract]
public interface ICalculator
{
[OperationContract]
int Add(int x, int y);
} [ServiceBehavior]
public class Cal : ICalculator
{
public int Add(int x, int y)
{
System.Threading.Thread.Sleep(5000);
return x + y;
}
}

服务寄宿:

 static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(kk.Cal));
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetUrl = new Uri("http://localhost:6666/meta");
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior);
host.AddServiceEndpoint(typeof(kk.ICalculator), new WSHttpBinding(), "http://localhost:6666");
host.Opened+=delegate{Console.WriteLine("Service start!");};
host.Open();
Console.ReadLine();
}

通过ServiceMetadataBehavior的HttpGetUrl可以设置服务的元数据地址,客户端通过这个地址获取到服务的全部信息。

先运行服务端。再按下列步骤在客户端添加服务引用

1.添加服务引用

2.输入服务公布的元数据地址。

3.在高级中选中生成异步操作。再点击2中的前往即可。

一、通过BeginAdd/EndBegin方法调用客户端。

生成成功后通过默认命名空间ServiceReference1获取到客户端,直接调用BeginAdd方法进行异步调用。

static void Main(string[] args)
{
ServiceReference1.CalculatorClient client = new ServiceReference1.CalculatorClient();
client.BeginAdd(1, 2, CallBack, client);
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(1000);
Console.WriteLine("{0}", i);
}
} public static void CallBack(IAsyncResult ar)
{
ServiceReference1.CalculatorClient client = ar.AsyncState as ServiceReference1.CalculatorClient;
int result = client.EndAdd(ar);
Console.WriteLine("Result:{0}", result);
}

BeginAdd的前两个参数是契约接口参数。第三个是回调方法,参数类型为IAsyncResult返回值为void的委托。第四个是Object类,这里将client客户端传进去,因为需要在回调方法中调用EndAdd方法得到结果。或者直接把client定义成static成员变量,这样就不需要传入了。

二、通过xxxCompleted添加委托。

static void Main(string[] args)
{
ServiceReference1.CalculatorClient client = new ServiceReference1.CalculatorClient();
client.AddCompleted += delegate(object sender, ServiceReference1.AddCompletedEventArgs e)
{
int[] para = e.UserState as int[];
int result = e.Result;
Console.WriteLine("Result:{0}+{1}={2}", para[0], para[1], result);
};
client.AddAsync(1, 2,new int[]{1,2});
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(1000);
Console.WriteLine("{0}", i);
}
}

Completed+=委托是上面的一种变形,直接通过completedEventArgs的Result属性获取结果,UserState获取附加参数。

上面两种异步调用实现效果为:

通过观察在客户端通过添加服务引用生成的代码,

public partial class CalculatorClient : System.ServiceModel.ClientBase<client2.ServiceReference1.ICalculator>, client2.ServiceReference1.ICalculator

发现ServiceReference1.CalculatorClient是继承自

public abstract class ClientBase<TChannel> : ICommunicationObject, IDisposable where TChannel : class

这也意味着我们可以自定义一个Cinent,而不需要去生成而产生很多无用的代码。

using System.ServiceModel;
using System.ServiceModel.Channels;
namespace client2
{
class Program
{
static void Main(string[] args)
{
myClient client = new myClient(new WSHttpBinding(), new EndpointAddress(new Uri("http://localhost:6666")));
int result=client.myChannel.Add(1, 2);
Console.WriteLine("{0}", result);
}
} public class myClient : ClientBase<kk.ICalculator>
{
public myClient(Binding bind, EndpointAddress addr)
: base(bind, addr)
{
}
public kk.ICalculator myChannel
{
get
{
return this.Channel;
}
}
}
}

myClient继承ClientBase并指定泛型契约,重写基类构造函数,指定Binding和EndpointAddress。并通过返回基类Channel属性。构造的时候传入服务端使用的绑定模式,和终结点地址。然后通过myChannel即可获取通道。其实这个ClientBase内部也是通过ChannelFactory<T>实现的,通过信道工厂创建信道,通过信道调用服务端方法。下面代码是通过信道工厂实现。

static void Main(string[] args)
{
ChannelFactory<kk.ICalculator> factory = new ChannelFactory<kk.ICalculator>(new WSHttpBinding(), new EndpointAddress(new Uri("http://localhost:6666")));
kk.ICalculator mychannel=factory.CreateChannel();
mychannel.Add(1, 2);
}

WCF-异步调用和两种客户端形式的更多相关文章

  1. WCF 异步调用问题

    添加引用时生成"勾选允许生成异步操作" Wcf异步调用三种方式: 第一种:直接调用异步方法 var serviceClient = new MyServiceClient(); s ...

  2. 保姆级别的RabbitMQ教程!一看就懂!(有安装教程,送安装需要的依赖包,送Java、Golang两种客户端教学Case)

    保姆级别的RabbitMQ教程!一看就懂!(有安装教程,送安装需要的依赖包,送Java.Golang两种客户端教学Case)   目录 什么是AMQP 和 JMS? 常见的MQ产品 安装RabbitM ...

  3. DLL调用的两种方式(IDE:VC6.0,C++)

    原文:http://www.cnblogs.com/Pickuper/articles/2050409.html DLL调用有两种方式,一种是静态调用,另外一种是动态调用 (一)静态调用 静态调用是一 ...

  4. Oracle的sql语句的两种判断形式

    Oracle的sql语句的两种判断形式 判断当前列同时改动当前列 判断一个情况改动其他值 一类情况详解:实现的是当num这一列的值为3时,就显示好 以此类推 1)case num when 3 the ...

  5. java SWing事件调用的两种机制

      Java(91)  /** * java swing中事件调用的两种机制: * (一)响应机制 * (二)回调机制 */ package test; import java.awt.*; impo ...

  6. JAVA客户端API调用memcached两种方式

    1. memcached client for java客户端API:memcached client for java 引入jar包:java-memcached-2.6.2.jar package ...

  7. WCF异步调用

    添加引用服务--高级--选中 生产异步操作 服务端接口操作 [OperationContract]int Add(int a, int b); 客户端: 引用服务:在引用服务时,左下角点击“高级”按钮 ...

  8. 异步编程的两种模型,闭包回调,和Lua的coroutine,到底哪一种消耗更大

    今天和人讨论了一下CPS变形为闭包回调(典型为C#和JS),以及Lua这种具有真正堆栈,可以yield和resume的coroutine,两种以同步的形式写异步处理逻辑的解决方案的优缺点.之后生出疑问 ...

  9. springcloud 服务调用的两种方式

    spring-cloud调用服务有两种方式,一种是Ribbon+RestTemplate, 另外一种是Feign.Ribbon是一个基于HTTP和TCP客户端的负载均衡器,其实feign也使用了rib ...

随机推荐

  1. 控制 MediaElement(播放、暂停、停止、音量和速度)

    控制 MediaElement(播放.暂停.停止.音量和速度) WPF中对于多媒体的支持非常完整,一般都是通过MediaElement来实现的. http://msdn.microsoft.com/z ...

  2. 跨域处理之Jsonp

    一.认识Jsonp JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式 ...

  3. sharepoint 2013 升级要求

    1. 安装过程合理: A. 可以同时在管理中心.两台前端.搜索服务器上安装重新发布的SP1补丁包(所提供的链接) B. 等待所有SP1补丁包安装完成,依次在管理中心.两台前端.搜索服务器上运行配置向导 ...

  4. golang plugin的依赖问题

    golang plugin的依赖问题 此文中涉及的plugin运行环境为mac 10.14,go版本为1.11 主要是想讨论一下插件依赖的第三方库的问题. 例子是在https://github.com ...

  5. 动态代理(CGLIB实现)

    CGLIB(Code Generation Library)是一个开源项目.可以直接对类进行增强,而不需要像JDK的动态代理,需要增强的类必须实现某接口 在使用Spring框架时,因为Spring框架 ...

  6. django 结合 OPTIONS方法 处理跨域请求(单个视图方法中)

    OPTIONS 方法比较少见,该方法用于请求服务器告知其支持哪些其他的功能和方法.通过 OPTIONS 方法,可以询问服务器具体支持哪些方法,或者服务器会使用什么样的方法来处理一些特殊资源.可以说这是 ...

  7. win7 下如何安装 Microsoft Web Application Stress Tool

    Microsoft Web Application Stress Tool是一个简单易用的性能压力测试工具,但因为其诞生的年代较早,在目前的win7系统下运行,会存在一些兼容性的问题,以下是我在实际使 ...

  8. C++基础知识-inline、const、mutable、this、static

    一.在类定义中实现成员函数inline 类内的成员函实现其实也叫作类内的成员函数定义. 这种直接在类的定义中实现的函数,会被当做inline内联函数来处理. 二.成员函数末尾的const const: ...

  9. 基于XMPP的即时通信系统的建立 — XMPP IQ详解

    XMPP详解 XMPP(eXtensible Messaging and Presence Protocol,可扩展消息处理和现场协议)是一种在两个地点间传递小型结构化数据的协议.在此基础上,XMPP ...

  10. 对drf视图的理解

    视图说明 1. 两个基类 1)APIView rest_framework.views.APIView APIView是REST framework提供的所有视图的基类,继承自Django的View父 ...