博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WCF系列教程之客户端异步调用服务
阅读量:7091 次
发布时间:2019-06-28

本文共 5258 字,大约阅读时间需要 17 分钟。

本文参考自http://www.cnblogs.com/wangweimutou/p/4409227.html,纯属读书笔记,加深记忆

一、简介

在前面的随笔中,详细的介绍了WCF客户端服务的调用方法,但是那些操作全都是同步的,所以我们需要很长的时间等待服务器的反馈,如何一台服务器的速度很慢,所以客户端得到结果就需要很长的时间,试想一下,如果客户端是个web项目,那么客户体验可想而知,所以为了不影响后续代码执行和用户的体验,就需要使用异步的方式来调用服务。注意这里的异步是完全针对客户端而言的,与WCF服务契约的方法是否异步无关,也就是在不改变操作契约的情况下,我们可以用同步或者异步的方式调用WCF服务。

 

二、操作示例

1、WCF服务层搭建:新建契约层、服务层、和WCF宿主,添加必须的引用(这里不会的参考本人前面的随笔),配置宿主,生成解决方案,打开Host.exe,开启服务。具体的代码如下:

ICalculate.cs

using System;using System.Collections.Generic;using System.Linq;using System.ServiceModel;using System.Text;using System.Threading.Tasks;namespace IService{    [ServiceContract]    public interface ICalculate    {        [OperationContract]        int Add(int a, int b);    }}

IUserInfo.cs

using System;using System.Collections.Generic;using System.Linq;using System.Runtime.Serialization;using System.ServiceModel;using System.Text;using System.Threading.Tasks;namespace IService{    [ServiceContract]    public interface IUserInfo    {        [OperationContract]        User[] GetInfo(int? id);    }    [DataContract]    public class User    {        [DataMember]        public int ID { get; set; }        [DataMember]        public string Name { get; set; }        [DataMember]        public int Age { get; set; }        [DataMember]        public string Nationality { get; set; }      }}

注:必须引入System.Runtime.Serialization命名空间,应为User类在被传输时必须是可序列化的,否则将无法传输

Calculate.cs

using IService;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Service{    public class Calculate : ICalculate    {        public int Add(int a, int b)        {            return a + b;        }    }}

UserInfo.cs

using IService;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Service{    public class UserInfo : IUserInfo    {        public User[] GetInfo(int? id)        {            List
Users = new List
(); Users.Add(new User { ID = 1, Name = "张三", Age = 11, Nationality = "China" }); Users.Add(new User { ID = 2, Name = "李四", Age = 12, Nationality = "English" }); Users.Add(new User { ID = 3, Name = "王五", Age = 13, Nationality = "American" }); if (id != null) { return Users.Where(x => x.ID == id).ToArray(); } else { return Users.ToArray(); } } }}

Program.cs

using System;using System.Collections.Generic;using System.Linq;using System.Text;using Service;using System.ServiceModel;namespace Host{    class Program    {        static void Main(string[] args)        {            using (ServiceHost host = new ServiceHost(typeof(Calculate)))            {                host.Opened += delegate { Console.WriteLine("服务已经启动,按任意键终止!"); };                host.Open();                Console.Read();            }        }    }}

App.Config

ok,打开Host.exe

服务开启成功!

 

2、新建名为Client的客户端控制台程序,通过添加引用的方式,异步调用WCF服务

添加添加对服务终结点地址http://localhost:6666/UserInfo/的引用,设置服务命名空间为UserInfoServiceNS,点击高级设置,勾选生成异步操作选项,生成客户端代理类和配置文件代码后,完成Client对服务的调用.

ok,开始编写program.cs代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Client.UserInfoServiceNS;namespace Client{    class Program    {        static void Main(string[] args)        {            UserInfoClient proxy = new UserInfoClient();            proxy.GetInfoCompleted += new EventHandler
(proxy_GetInfoCompleted);//注册proxy_GetInfoCompleted到proxy.GetInfoCompleted中 proxy.GetInfoAsync(null);//开始异步调用 Console.WriteLine("此字符串在调用方法前输出,说明异步调用成功!"); Console.Read(); } static void proxy_GetInfoCompleted(object sender, GetInfoCompletedEventArgs e) { User[] Users = e.Result.ToArray(); Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}", "ID", "Name", "Age", "Nationality"); for (int i = 0; i < Users.Length; i++) { Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}", Users[i].ID.ToString(), Users[i].Name.ToString(), Users[i].Age.ToString(), Users[i].Nationality.ToString()); } } }}

从上面的代码可以看出WCF服务端和WCF客户端采用了事件驱动机制,也就是所谓的发布-订阅模式,不了解的话,请参考本人的,当proxy.GetInfoAsync(null)从服务端获取数据成功之后,即开始执行EventHandler<T>上绑定的方法.

public delegate void EventHandler
(object sender, TEventArgs e);

通过参数类型TEventArgsResult可以获得返回结果

User[] Users = e.Result.ToArray();

 

 

三、通过svcutil生成客户端代理类,并通过重写客户端的服务契约,完成对服务端服务的异步吊用

新建名为Client1的客户端控制台程序,通过svcutil.exe工具生成的客户端代理类,,异步调用WCF服务

(1)、打开cmd,输入cd C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin

(2)、输入svcutil.exe   /out:f:\UserInfoClient.cs  /config:f:\App.config  http://localhost:6666/UserInfo/  /a  /tcv:Version35

 

ok,生成成功

(5)、将生成的文件拷贝到项目中,引入System.Runtime.Serialization命名空间和System.ServiceModel命名空间

(6)、剩下的步骤和上面的一样

 

你可能感兴趣的文章
[译] 系列教程:选择准备安装的 TensorFlow 类型
查看>>
Webhook到底是个啥?
查看>>
Flutter学习 ---- TravisCI加持
查看>>
借用UAC完成的提权思路分享
查看>>
『中级篇』 Linux网络命名空间(25)
查看>>
JS计算精度小记
查看>>
js的各种距离计算(较全)
查看>>
微信小程序异步API为Promise简化异步编程
查看>>
关于java泛型大大小小的那些事
查看>>
此面试题版本落后-请勿观看
查看>>
Stream流与Lambda表达式(三) 静态工厂类Collectors
查看>>
javascript 面向对象 new 关键字 原型链 构造函数
查看>>
日剧·日综资源集合(建议收藏)
查看>>
[译]go错误处理
查看>>
redis 使用 get 命令读取 bitmap 类型的数据
查看>>
中国移动清退3G进行时
查看>>
k8s技术预研14--kubernetes API详解
查看>>
植物的Transcription Factor挖掘笔记
查看>>
你不得不读的书籍清单
查看>>
java源码-ArrayList
查看>>