化零为整WCF(12) - 并发和限流(Concurrent和Throttle)

简介:
[索引页]
[源码下载] 


化零为整WCF(12) - 并发和限流(Concurrent和Throttle)


作者: webabcd


介绍
WCF(Windows Communication Foundation) - 并发(Concurrent):
    1、ConcurrencyMode.Single:单线程并发模式。系统自动加锁,无并发问题
    ·InstanceContextMode.PerCall:每个线程都会被分配一个新的实例
    ·InstanceContextMode.PerSession:每个Session被分配一个新的实例,每个Session内同时只会有一个线程操作实例
    ·InstanceContextMode.Single:唯一实例,并发调用只会有一个线程操作实例
    2、ConcurrencyMode.Reentrant:可重入的单线程并发模式。有可重入(回调)操作时,此模式才会生效,从回调返回的线程会进入队列尾部排队
    ·InstanceContextMode.PerCall:每个线程都会被分配一个新的实例,当有回调操作时如果使用Single并发模式的话就会产生死锁(1、调用服务端;2、回调客户端;3、返回服务端,1的时候锁定了,到3的时候就无法执行了,所以死锁了),此时应该用Reentrant并发模式
    ·InstanceContextMode.PerSession:每个Session被分配一个新的实例,每个Session内同时只会有一个线程操作实例,Session内可重入
    ·InstanceContextMode.Single:唯一实例,并发调用只会有一个线程操作实例,全局可重入
    3、ConcurrencyMode.Multiple:多线程并发模式。系统不会自动加锁,有并发问题
    ·InstanceContextMode.PerCall:每个线程都会被分配一个新的实例,无并发问题
    ·InstanceContextMode.PerSession:每个Session被分配一个新的实例,每个Session内多线程操作实例的话会有并发问题
    ·InstanceContextMode.Single:唯一实例,允许多线程并发操作实例,有并发问题

WCF(Windows Communication Foundation) - 限流(Throttle):
<behaviors> 
                <serviceBehaviors> 
                        <behavior name="BehaviorPerCall"> 
                                <!--httpGetEnabled - 指示是否发布服务元数据以便使用 HTTP/GET 请求进行检索,如果发布 WSDL,则为 true,否则为 false,默认值为 false--> 
                                <serviceMetadata httpGetEnabled="true"/> 
                                <!--maxConcurrentCalls - 服务中同时存在的最大活动消息数,默认值为 16--> 
                                <!--maxConcurrentInstances - 服务中同时存在的最大服务实例数,默认值为 Int32.MaxValue--> 
                                <!--maxConcurrentSessions - 服务中同时存在的最大会话数,默认值为 10--> 
                                <serviceThrottling maxConcurrentCalls="" maxConcurrentInstances="" maxConcurrentSessions="" /> 
                        </behavior> 
                        <behavior name="BehaviorPerSession"> 
                                <serviceMetadata httpGetEnabled="true"/> 
                                <serviceThrottling maxConcurrentCalls="" maxConcurrentInstances="" maxConcurrentSessions="" /> 
                        </behavior> 
                        <behavior name="BehaviorSingle"> 
                                <serviceMetadata httpGetEnabled="true"/> 
                                <serviceThrottling maxConcurrentCalls="" maxConcurrentInstances="1" maxConcurrentSessions="" /> 
                        </behavior> 
                </serviceBehaviors> 
        </behaviors>
 
示例(以ConcurrencyMode.Reentrant为例)
1、服务

IDuplexReentrant.cs
InBlock.gif using System; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.Linq; 
InBlock.gif using System.Text; 
InBlock.gif 
InBlock.gif using System.ServiceModel; 
InBlock.gif 
InBlock.gif namespace WCF.ServiceLib.Message 
InBlock.gif
InBlock.gif         /// <summary> 
InBlock.gif         /// IDuplexReentrant接口(演示ConcurrencyMode.Reentrant) 
InBlock.gif         /// </summary> 
InBlock.gif         /// <remarks> 
InBlock.gif        /// IDuplexReentrantCallback - 回调接口 
InBlock.gif        /// </remarks> 

InBlock.gif        [ServiceContract(CallbackContract =  typeof(IDuplexReentrantCallback))] 
InBlock.gif         public  interface IDuplexReentrant 
InBlock.gif        { 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// Hello 
InBlock.gif                 /// </summary> 
InBlock.gif                 /// <param name="name">名字</param> 
InBlock.gif                [OperationContract] 
InBlock.gif                 void HelloDuplexReentrant( string name); 
InBlock.gif        } 
InBlock.gif 
InBlock.gif         /// <summary> 
InBlock.gif         /// IDuplexReentrant回调接口 
InBlock.gif         /// </summary> 
InBlock.gif         public  interface IDuplexReentrantCallback 
InBlock.gif        { 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// Hello 
InBlock.gif                 /// </summary> 
InBlock.gif                 /// <param name="name"></param> 
InBlock.gif                [OperationContract] 
InBlock.gif                 void HelloDuplexReentrantCallback( string name); 
InBlock.gif        } 
InBlock.gif}
 
DuplexReentrant.cs
InBlock.gif using System; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.Linq; 
InBlock.gif using System.Text; 
InBlock.gif 
InBlock.gif using System.ServiceModel; 
InBlock.gif 
InBlock.gif namespace WCF.ServiceLib.Message 
InBlock.gif
InBlock.gif         /// <summary> 
InBlock.gif         /// DuplexReentrant类 (演示ConcurrencyMode.Reentrant) 
InBlock.gif         /// </summary> 
InBlock.gif         /// <remarks> 
InBlock.gif        /// ConcurrencyMode - 获取或设置一个值,该值指示服务是支持单线程、多线程还是支持可重入调用。默认值为 System.ServiceModel.ConcurrencyMode.Single。 
InBlock.gif        /// Single - 服务实例是单线程的,且不接受可重入调用。 
InBlock.gif        /// Reentrant - 服务实例是单线程的,且接受可重入调用。 
InBlock.gif        /// Multiple - 服务实例是多线程的。 
InBlock.gif        /// </remarks> 

InBlock.gif        [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)] 
InBlock.gif         public  class DuplexReentrant : IDuplexReentrant 
InBlock.gif        { 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// Hello 
InBlock.gif                 /// </summary> 
InBlock.gif                 /// <param name="name">名字</param> 
InBlock.gif                 public  void HelloDuplexReentrant( string name) 
InBlock.gif                { 
InBlock.gif                         // 声明回调接口 
InBlock.gif                        IDuplexReentrantCallback callback = OperationContext.Current.GetCallbackChannel<IDuplexReentrantCallback>(); 
InBlock.gif 
InBlock.gif                         // 调用回调接口中的方法 
InBlock.gif                        callback.HelloDuplexReentrantCallback(name); 
InBlock.gif                } 
InBlock.gif        } 
InBlock.gif}
 
 
2、宿主
DuplexReentrant.cs
InBlock.gif using System; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.Linq; 
InBlock.gif using System.Text; 
InBlock.gif 
InBlock.gif using System.ServiceModel; 
InBlock.gif 
InBlock.gif namespace WCF.ServiceHost2.Message 
InBlock.gif
InBlock.gif         /// <summary> 
InBlock.gif         /// host WCF.ServiceLib.Message.DuplexReentrant的类 
InBlock.gif         /// </summary> 
InBlock.gif         public  class DuplexReentrant 
InBlock.gif        { 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 启动WCF.ServiceLib.Message.DuplexReentrant服务 
InBlock.gif                 /// </summary> 
InBlock.gif                 public  void Launch() 
InBlock.gif                { 
InBlock.gif                         using (ServiceHost host =  new ServiceHost( typeof(WCF.ServiceLib.Message.DuplexReentrant))) 
InBlock.gif                        { 
InBlock.gif                                host.Open(); 
InBlock.gif 
InBlock.gif                                Console.WriteLine( "服务已启动(WCF.ServiceLib.Message.DuplexReentrant)"); 
InBlock.gif                                Console.WriteLine( "按<ENTER>停止服务"); 
InBlock.gif                                Console.ReadLine(); 
InBlock.gif 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif        } 
InBlock.gif}
 
App.config
<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
        <system.serviceModel> 
                <services> 
                        <!--name - 提供服务的类名--> 
                        <!--behaviorConfiguration - 指定相关的行为配置--> 
                        <service name="WCF.ServiceLib.Message.DuplexReentrant" behaviorConfiguration="MessageBehavior"> 
                                <!--address - 服务地址--> 
                                <!--binding - 通信方式--> 
                                <!--contract - 服务契约--> 
                                <endpoint address="Message/DuplexReentrant" binding="netTcpBinding" contract="WCF.ServiceLib.Message.IDuplexReentrant" /> 
                                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
                                <host> 
                                        <baseAddresses> 
                                                <add baseAddress="http://localhost:12345/Message/DuplexReentrant"/> 
                                                <add baseAddress="net.tcp://localhost:54321/"/> 
                                        </baseAddresses> 
                                </host> 
                        </service> 
                </services> 
                <behaviors> 
                        <serviceBehaviors> 
                                <behavior name="MessageBehavior"> 
                                        <!--httpGetEnabled - 指示是否发布服务元数据以便使用 HTTP/GET 请求进行检索,如果发布 WSDL,则为 true,否则为 false,默认值为 false--> 
                                        <serviceMetadata httpGetEnabled="true" /> 
                                        <serviceDebug includeExceptionDetailInFaults="true"/> 
                                </behavior> 
                        </serviceBehaviors> 
                </behaviors> 
        </system.serviceModel> 
</configuration>
 
 
3、客户端
DuplexReentrant.cs
InBlock.gif using System; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.Linq; 
InBlock.gif using System.Text; 
InBlock.gif 
InBlock.gif using System.ServiceModel; 
InBlock.gif using System.Windows.Forms; 
InBlock.gif 
InBlock.gif namespace Client2.Message 
InBlock.gif
InBlock.gif         /// <summary> 
InBlock.gif         /// 演示Message.DuplexReentrant的类 
InBlock.gif         /// </summary> 
InBlock.gif         public  class DuplexReentrant 
InBlock.gif        { 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// Hello 
InBlock.gif                 /// </summary> 
InBlock.gif                 /// <param name="name">名字</param> 
InBlock.gif                 public  void HelloDulexReentrant( string name) 
InBlock.gif                { 
InBlock.gif                        var ct =  new Client2.Message.ReentrantCallbackType(); 
InBlock.gif                        var ctx =  new InstanceContext(ct); 
InBlock.gif 
InBlock.gif                        var proxy =  new MessageSvc.DuplexReentrant.DuplexReentrantClient(ctx); 
InBlock.gif 
InBlock.gif                        proxy.HelloDuplexReentrant(name); 
InBlock.gif                } 
InBlock.gif        } 
InBlock.gif}
 
ReentrantCallbackType.cs
InBlock.gif using System; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.Linq; 
InBlock.gif using System.Text; 
InBlock.gif 
InBlock.gif using System.Windows.Forms; 
InBlock.gif 
InBlock.gif namespace Client2.Message 
InBlock.gif
InBlock.gif         /// <summary> 
InBlock.gif         /// 实现回调接口 
InBlock.gif         /// </summary> 
InBlock.gif         /// <remarks> 
InBlock.gif        /// CallbackBehavior - 在客户端应用程序中配置回调服务实现 
InBlock.gif        /// UseSynchronizationContext - 如果对服务的所有调用都必须在 System.Threading.SynchronizationContext 指定的线程上运行,则为 true;否则为false。默认值为 true。 
InBlock.gif        /// </remarks> 

InBlock.gif        [System.ServiceModel.CallbackBehavior(UseSynchronizationContext =  false)] 
InBlock.gif         public  class ReentrantCallbackType : MessageSvc.DuplexReentrant.IDuplexReentrantCallback 
InBlock.gif        { 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// Hello 
InBlock.gif                 /// </summary> 
InBlock.gif                 /// <param name="name">名字</param> 
InBlock.gif                 public  void HelloDuplexReentrantCallback( string name) 
InBlock.gif                { 
InBlock.gif                        MessageBox.Show( "Hello: " + name); 
InBlock.gif                } 
InBlock.gif        } 
InBlock.gif}
 
App.config
<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
        <system.serviceModel> 
                <client> 
                        <endpoint address="net.tcp://localhost:54321/Message/DuplexReentrant" 
                                binding="netTcpBinding" contract="MessageSvc.DuplexReentrant.IDuplexReentrant"> 
                        </endpoint> 
                </client> 
        </system.serviceModel> 
</configuration>
 
 
运行结果:
单击"btnDuplexReentrant"按钮后弹出提示框,显示"Hello: webabcd"


OK
[源码下载]




     本文转自webabcd 51CTO博客,原文链接: http://blog.51cto.com/webabcd/344154 ,如需转载请自行联系原作者
相关文章
|
安全 编译器 Windows
|
10月前
|
前端开发
WCF更新服务引用报错的原因之一
WCF更新服务引用报错的原因之一
|
9月前
|
C# 数据安全/隐私保护
c#如何创建WCF服务到发布(SqlServer版已经验证)
c#如何创建WCF服务到发布(SqlServer版已经验证)
38 0