前言:
- 在上一篇WCF初探-10:WCF客户端调用服务 中,我详细介绍了WCF客户端调用服务的方法,但是,这些操作都是同步进行的。有时我们需要长时间处理应用程序并得到返回结果,但又不想影响程序后面代码部分的执行,这时我们就需要考虑使用异步的方式来调用服务。注意这里的异步是完全针对客户端而言的,与WCF服务契约的方法是否异步无关,也就是在不改变操作契约的情况下,我们可以用同步或者异步的方式调用WCF服务。
WCF客户端异步调用服务方式:
- 通过代理类异步调用服务。就需要通过使用事件驱动的异步调用模型,客户端可以对此接口异步调用操作。基于事件的异步模型设计准则规定,如果返回了多个值,则一个值会作为 Result 属性返回,其他值会作为 EventArgs 对象上的属性返回。 因此产生的结果之一是,如果客户端使用基于事件的异步命令选项导入元数据,且该操作返回多个值,则默认的 EventArgs 对象返回一个值作为 Result 属性,返回的其余值是 EventArgs 对象的属性。如果要将消息对象作为 Result 属性来接收并要使返回的值作为该对象上的属性,请使用 /messageContract 命令选项。 这会生成一个签名,该签名会将响应消息作为 EventArgs 对象上的 Result 属性返回。 然后,所有内部返回值就都是响应消息对象的属性了。
- 使用通道工厂以异步方式调用操作。使用 ChannelFactory<TChannel> 时,不支持事件驱动的异步调用模型。这时我们需要异步重写服务契约的接口,每个方法都包含一组beginXXX和endXXX,XXX代表方法名。并且我们需要将异步操作的方法上的 AsyncPattern 属性设置为 true。前一个方法启动调用,而后一个方法在操作完成时检索结果。
WCF客户端异步调用服务示例:
- 工程结构如下图所示:
- 工程结构说明:
- Service:类库程序,定义服务契约和实现,里面包含User数据契约和GetInfo()获取用户信息的服务契约方法。
IUserInfo.cs的代码如下:
using System.ServiceModel; using System.Collections.Generic; using System.Runtime.Serialization; namespace Service { [ServiceContract] public interface IUserInfo { [OperationContract] User[] GetInfo(int? id=null); } [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; } } }