| 加入收藏| 设为首页| 联系我们

首页 站长学习 站长之家 源码下载 建站素材 书籍教程 常用工具
 您现在的位置: 动力中国 >> 网络编程 >> ASP.NET教程 >> 文章正文  
 [图文]WCF:双向通讯,枷锁机制,线程并发的一些简单理解(一)
 

WCF:双向通讯,枷锁机制,线程并发的一些简单理解(一)

http://www.domcn.org  文章来源:本站收藏  点击数:

  关键字:WCF:双向通讯,枷锁机制,线程并发的一些简单理解(一)

WCF: 双向通讯,枷锁机制,线程并发的一些简单理解

简单的来说,双向通讯是这样的一种机制,就是服务端与客户端的身份是可换的,服务示例可以回调客户端的操作,当一个服务契约被定义在服务端的时候,有时候我门的业务逻辑要求我门进行相应的回调操作。标准的服务契约定义了能够被客户端调用的服务操作。回调契约定义了能够被服务端调用的客户端操作。因此客户端必须具有实现回调契约的义务和宿主回调对象的能力。每当客户端调用具有回调操作的服务端示例操作的时候,客户端必须提供足够的信息以使服务端能够寻址到客户端并执行相应的回调操作。

默认情况下,WCF服务被配置在单线程下,这意味着在任何服务实例的给定时间,有切仅有一个线程去处理消息,因此,当服务实例正在处理从客户端传来的消息的时候,服务端应当拒绝接受任何其他来自客户端的调用,这中机制就是枷锁。这种机制的提出,保证了正在处理的消息能够有效,安全的处理完毕。

请首先理解枷锁机制是必须而且有时候是不可避免的。但是由于我门的业务逻辑的灵活性,有时候我门却试图在我门能够控制局面的情况下,摘掉枷锁。所以本文以下的描述,就是关于这个问题的一些探讨。

如果我门试图在一个单线程的服务操作的执行中执行一个客户端的回调操作,死锁将会发生,这是WCF默认的并发模式下的枷锁机制的原因。当回调操作在客户端被调用,服务端必须等待客户端的返回值,才能执行接下来的操作,然而,这时的服务实例却因为处理当前的操作已经被加锁,所以,死锁不可避免。哈,有趣的是,如果你这样做了,WCF并不会抛出关于死锁的异常,而会抛出一个InvalidOperationEXception异常.

上边我门说过,由于我门独特的业务逻辑,我门又不得不在一个服务操作的执行中间进行客户端的回调,那得如何处理呢?我想,可以从这几方面进行尝试:

一:首先,也许大家普遍知道的是,设置ConCurrendMode的属性为Multiple,这将会开启一个多线程模式,但是我请你注意,并非一定设置如此,在默认的Single模式下也可以进行客户端的回调,不过需要做些额外的工作,后边我会简单介绍一个实例,这个示例就是工作在单线程下。当然对于初学者来说,简单设置Multiple是最好的办法,因为本身WCF程序就不好调试,更何况是双向通讯呢,我觉得没有什么比WCF的异常错误带来的挫败感更让人灰心丧气,而且通常对它无计可施。

二:设置ConCurrendMode的属性为Reentrant,这其实就是单线程下的一种工作方式,但是当你触发一个客户端的回调操作的时候,WCF将会释放那个枷锁,所以服务实例可以处理来自回调操作的消息。但是我请你无比理解上述几句话,也就是说在执行客户端回调操作的时候,服务端示例并没有进行枷锁机制。我门说过,WCF默认的情况下,是进行加锁,这是有必要的。在上边这中情况下,并没有进行枷锁会出现什么情况呢?如果一个服务示例在执行一个服务操作的中间进行客户端回调操作,服务端暂休息,等待回调操作返回消息以便进行接下来的操作。同样在这个过程中,就是在服务端间歇的时候,它可以接受任何客户端的消息,不仅仅是回调操作的消息,如果客户端又进行了一个服务调用,服务示例就会执行这个调用,这中情况下,是不能保证在回调操作前和回调操作后的数据状态以及完整性的一致性。因此,如果你使用这种方法,请确保没有其他客户端的调用或者说请确保服务端数据的安全性。

三:设置回调方法的操作属性为Isoneway.这允许WCF触发客户端回调操作而没有请求一个枷锁,这是一种强制手法,强制客户端不回传消息(当然我门必须有适合如此场景的业务逻辑才行),因此,服务端就没有必要进行枷锁。后边介绍的事例也会采用本方法。

我想通过一个示例来进行接下来的阐述,这个示例的作者是jeff.barnes,他写了大量的关于WCF的文章,更多文章请参阅http://jeffbarnes.net/portal/blogs/jeff_barnes/default.aspx,我觉得老外写的示例总是很个性而又很深刻。这个示例采用了publish-subscribe 设计模式,这个模式非常非常重要,个人觉得,很多Soa框架的核心主要是利用了两把利箭,一个就是publish-subscribe模式,另一个是事件驱动。

回到我门的示例。简单讲一下这个示例的场景。这个场景,就是帮助一个party的主人去记录客人和他们消费的beer的设计。每一个顾客(subscribes)通过参加party来订阅服务。当一些有趣的事情发生了,譬如顾客参加/离开了聚会或者消费啤酒的情况,那个服务,把这些相关信息publish那些订阅者。

本示例执行如图:
   

我门开始我门的设计。我定义一个服务契约,就是一个用ServiceContract修饰的接口,然后在服务契约中定义CallbackContract = typeof(IBeerInventoryCallback),这创造了服务端和客户端的两个接口的联合。为了消费服务操作,客户端必须实现回调契约,并且宿主实现回调契约的对象,这中机制其实跟服务端没有任何区别,只是WCF为我门做了些工作,为了简化代码,在客户端我门不需要声名一个ServiceHost,然后宿主服务示例,我门仅仅将实现回调操作的事例放在一个上下文中就可以了,或者说用一个上下文去获取,譬如我门可以这样写:InstanceContext(new CallbackObject());(callbackobject是一个实现回调操作的对象)。很多的场景我门都会用到上下文这个概念,我想这也是很多人困惑的地方,上下文这个概念比较复杂,可以这样理解,上下文是一种逻辑线程,我门说回调实现了服务端和客户端的联合,这也就不可避免的让服务端的线程和客户端的线程联合在一起,我门的业务逻辑的执行往往需要在这两个线程中执行,出与这中考虑,WCF提出了上下文的机制,可以简单的理解为,这中机制的提出,屏蔽了服务端线程和客户端线程的差异,使得业务逻辑的执行好象是在一个线程中执行。因此,当我门在某一端,譬如服务端执行某些操作的时候可以获取客户端的一些相关对象。譬如,操作上下文,我门在编码的时候,也许用到过,OperationContext.Current.GetCallbackChannel<T>();,但是还是请你注意,就象这个操作的涵义本身,它获取的不是实现回调操作的对象而是一个回调通道对象。但是这个Channel对象可以跟回调对象暗中通信。我门体会不到这中差异,感觉就象是我门在操作回调对象。到底Channel对象如何跟回调对象通信,我不了解,但是做为Developer来说,我门没必要过分追究细节。当然你了解的话,可以告诉我。


WCF:双向通讯,枷锁机制,线程并发的一些简单理解(一)
  • 上一篇文章:

  • 下一篇文章:
  •  热门文章
    普通文章 电子邮件改头换面 四公司畅谈未
    普通文章 PC病毒史上最声名狼藉的八大病
    普通文章 Rails系统中的AJAX开发技术简析
    普通文章 基于ASP.NET AJAX框架实现表单
    普通文章 开发ASP.NET AJAX客户端定制行
    普通文章 用JFreeChart对JSP报表进行增强
    普通文章 SQL Server 2005上的CLR和ADO.
    普通文章 SQL Server 2005的XML支持机制
    普通文章 Firefox中标签式浏览技巧大全
    普通文章 Tomcat中的Session和Cookie大揭
     
     推荐文章
    推荐文章 把Google地图嵌入网页 就是这么
    推荐文章 迅雷搜索候选资源出错的解决
    推荐文章 轻松去除迅雷里的各种广告和资
    推荐文章 突破限制 免费领养到QQ空间五级
    推荐文章 Rational统一过程RUP贴近中小软
    推荐文章 构建自己的轻量级XML DOM分析程
    推荐文章 WPS Office 2007技巧:妙用配置
    推荐文章 Excel 2007:求余数函数实用进阶
    推荐文章 浅谈ASP.NET的Postback
    推荐文章 软件开发中项目需求管理简述
     
     相关文章
    没有相关文章
    设为首页 | 加入收藏 | 广告合作 | 联系站长 | 版权申明 |
    动力中国为网友提供免费学习资料,可用资源,如果您认为我们的相关内容侵害到了您的权利请联系管理员
    Copyright © 2006-2008 domcn.org All Rights Reserved.