对于WCF中通讯的双方来说,客户端可以异步的调用服务;服务端对服务也能以异步的方式实现。

目录:

1.WCF客户端异步调用服务

2.服务端的异步实现

WCF客户端异步调用服务主要通过生成异步的代理类,然后调用其中的异步方法来实现异步调用。

异步代理类的生成:

通过SvcUtil /async 直接生产异步代理;

通过添加应用的方式,点击”添加引用“的“高级”按钮,在弹出来的对话框中选择“生成异步”。如图:

生成的异步调用代理类部分借口:

[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]

public System.IAsyncResult BeginAdd(int x, int y, System.AsyncCallback callback, object asyncState) {

return base.Channel.BeginAdd(x, y, callback, asyncState);

}

public void AddAsync(int x, int y) {

this.AddAsync(x, y, null);

}

public void AddAsync(int x, int y, object userState) {

if ((this.onBeginAddDelegate == null)) {

this.onBeginAddDelegate = new BeginOperationDelegate(this.OnBeginAdd);

}

if ((this.onEndAddDelegate == null)) {

this.onEndAddDelegate = new EndOperationDelegate(this.OnEndAdd);

}

if ((this.onAddCompletedDelegate == null)) {

this.onAddCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnAddCompleted);

}

base.InvokeAsync(this.onBeginAddDelegate, new object[] {

x,

y}, this.onEndAddDelegate, this.onAddCompletedDelegate, userState);

}

1、客户端异步调用服务

客户端异步调用服务主要方式有几种:

1.1、直接调用异步方法:

在生成的代理类中,有BeginAdd\EndAdd等服务契约中定义的Add操作的异步实现。直接调用BeginAdd方法,实现客户端异步调用服务端方法。在调用BeginAdd方法后,可执行一些其他操作,这些操作与服务端Add调用并行执行,Add调用最终通过EndAdd方法得到。

测试代码如下:

客户端代码:

IAsyncResult asyncResult = calculatorClient.BeginAdd(1, for (int i = 0; i < 10; i++)

{

Console.WriteLine(i);

}

int resul = calculatorClient.EndAdd(asyncResult);

Console.WriteLine(string.Format("计算结果:{0}",resul));

服务端代码:

public int Add(int x, int y)

{

for (int i = 0; i < 20; i++)

{

Console.WriteLine(i);

}

Console.WriteLine("开始计算...");

return x + y;

}

服务端输出如下:

客户端输出如下:

这种方式使用了EndAdd方法,如果服务端没有执行完成,当前线程会被阻塞直到异步调用的服务完成后结束。如客户端代码保持不变,将服务实现改为如下:

for (int i = 0; i < 20; i++)

{

Console.WriteLine(i);

}

Thread.Sleep(5000);

Console.WriteLine("开始计算...");

return x + y;

如果在服务端让线程睡眠几秒,就可看到客户端会被阻塞:

1.2、通过回调的方式异步调用服务:

在生成的异步调用代理类中,还可以通过回调用服务:

IAsyncResult asyncResult = calculatorClient.BeginAdd(1, 2,

delegate(IAsyncResult asyncResult)

{

int [] array = asyncResult.AsyncState as int [];

int result= calculatorClient.EndAdd(asyncResult1);

calculatorClient.close()

Console.WriteLine(string.Format("{0}+{1}={2}", array[0], array[1], result));

}, new []{1,2});

这种方式是对服务的异步调用完成以后,自动调用回调来获取结果。

1.3、通过为异步操作注册事件

//进行异步调用

calculatorClient.AddAsync(10, 36, new[] { 1000 });

//为异步调用完成定义触发事件

calculatorClient.AddCompleted += calculatorClient_AddCompleted;

Console.WriteLine("服务调用完成...");

Console.ReadKey();

//异步调用完成后执行

privatestaticvoid calculatorClient_AddCompleted(object obj, AddCompletedEventArgs args)

{

var array = args.UserState as int[];

int result = args.Result;

Console.WriteLine(result);

}

2、服务的异步实现:

将服务实现定义成异步的方式,需要将OperationContract的AsyncPattern设置为true;应用到BeginXX接口上,并且此操作的最后两个参数必须为AsyncCallback ,object;需要有一个EndXX(IAsyncResult asyncResult)的接口与异步调用的接口匹配。需要注意的是EndXX(IAsyncResult asyncResult)不能再次声明为契约接口,也就是不能再标记为OperationContract。

将服务定义为异步服务,契约定义如下 :

[OperationContract(AsyncPattern = true)]

IAsyncResult BeginCalculator

(int x,int y ,AsyncCallback asyncCallback, object state);

void EndCalculator(IAsyncResult);

然后在实现契约接口的服务中,将方法实现为异步的。

将契约接口声明为单向,也就是OneWay,这样客户端对此服务接口调用就是异步的。因为它无需等待服务端返回,客户端只需将消息发送到传输层就立即返回。

那能不能将将这种客户端对服务端的异步调用直接标记为单向的,那是不是可以不用生成异步代理类(即上述SvcUtil /Ayncs或者在添加引用时声明将代理类生成异步操作)?答案是否定的,因为OneWay要求方法的返回值为void,而异步的方法需要IAsyncResult最为返回值,这两者矛盾的。

WCF中的异步实现的更多相关文章

  1. 转 WCF中同步和异步通讯总结

    我这样分个类: WCF中, 以同步.异步角度考虑通讯的方式分为四种:跨进程同步.跨进程异步.发送队列端同步.发送队列端异步.之所以造成这样的结果源于两个因素,一个是传统概念上的同异步,一个是对于WCF ...

  2. WCF初探-28:WCF中的并发

    理解WCF中的并发机制 在对WCF并发机制进行理解时,必须对WCF初探-27:WCF中的实例化进行理解,因为WCF中的并发特点是伴随着服务实例上下文实现的.WCF的实例上下文模型可以通过Instanc ...

  3. 跟我一起学WCF(11)——WCF中队列服务详解

    一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务队列的方法来支持客户端 ...

  4. WCF技术剖析之十一:异步操作在WCF中的应用(上篇)

    原文:WCF技术剖析之十一:异步操作在WCF中的应用(上篇) 按照操作执行所需的资源类型,我们可以将操作分为CPU绑定型(CPU Bound)操作和I/O绑定型(I/O Bound)操作.对于前者,操 ...

  5. WCF技术剖析之十一:异步操作在WCF中的应用(下篇)

    原文:WCF技术剖析之十一:异步操作在WCF中的应用(下篇) 说完了客户端的异步服务调用(参阅WCF技术剖析之十一:异步操作在WCF中的应用(上篇)),我们在来谈谈服务端如何通过异步的方式为服务提供实 ...

  6. WCF中队列服务详解

    WCF中队列服务详解 一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务 ...

  7. WCF中的AsyncPattern

    WCF中的AsyncPattern   (系列博文源自 http://pfelix.wordpress.com/,由笔者翻译并整理,转载请注明) 在wcf 的 service contract中, 服 ...

  8. WCF中,通过C#代码或App.config配置文件创建ServiceHost类

    C# static void Main(string[] args) { //创建宿主的基地址 Uri baseAddress = new Uri("http://localhost:808 ...

  9. WCF学习之旅—WCF中传统的异常处理(十六)

    WCF中的异常处理 在软件开发过程中,不可能没有异常的出现,所以在开发过程中,对不可预知的异常进行解决时,异常处理显得尤为重要.对于一般的.NET系统来说,我们简单地借助try/catch可以很容易地 ...

随机推荐

  1. 常用近百个js代码汇总

    //檢查空串 function isEmpty(str){ )) return (true); else return(false); } //檢查是否未數字 function isDigit(the ...

  2. 关于axis2.1.6与websphere7的包冲突问题的解决方式

    1,复制axis2.1.6内的module目录内的全部文件到lib 并改动扩展名为.jar 2,删除module目录(可选,不删除也能够) 3,部署到was 4,设置was相应应用程序的类载入方案为父 ...

  3. 2016/05/25 empty() 与 isset()的区别

    对于初学php的人来说,empty()和和isset()用法的区别是很难搞清楚的,他们的用法的差别不仔细去琢磨的话确实很难弄清楚. 先说一下他们的共同点: 都可以判定一个变量是否为空: 都返回bool ...

  4. Codeforces 768 E. Game of Stones 博弈DP

    E. Game of Stones   Sam has been teaching Jon the Game of Stones to sharpen his mind and help him de ...

  5. Koa2学习(五)中间件

    Koa2学习(五)中间件 Koa2通过app.use(function)方法来注册中间件. 所有的http请求都会依次调用app.use()方法,所以中间件的使用顺序非常重要. 中间件的执行顺序 官方 ...

  6. EJB3.0

    由于EJB2.0的复杂性,在Spring和Hibernate[1]  等轻量级框架出现后,大量的用户转向应用轻量级框架.在大家的呼声中, EJB 期待已久的EJB3.0规范终于发布了.在本文中将对新的 ...

  7. GoodUI:页面布局的技巧和设计理念

    http://goodui.org/ 中文翻译:http://www.cnblogs.com/Wayou/p/goodui.html 一年了,小小少年从幼年期过渡到成长期要开始加速冲刺了.毕竟钻头就是 ...

  8. Android Studio配置完毕Genymotion 看不到Genymotion图标

    没有打开toolBar想要看到genymotion插件图标,AndroidStudio单击视图(view)>工具栏显示工具栏(toolbar)

  9. CentOS 7.2更改网卡名称

    背景 没啥背景,就是VMWare装的CentOS虚拟机的自带网卡名有点乱,想重新定义一下. 环境 1.VMWare虚拟机 6张网卡 2.系统 [root@localhost ~]# cat /etc/ ...

  10. 在Main Thread中使用异步

    Whenever you first start an Android application, a thread called "main" is automatically c ...