zoukankan      html  css  js  c++  java
  • 化零为整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
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using System.ServiceModel;

    namespace WCF.ServiceLib.Message
    {
        
    /// <summary>
        
    /// IDuplexReentrant接口(演示ConcurrencyMode.Reentrant)
        
    /// </summary>
        
    /// <remarks>
        
    /// IDuplexReentrantCallback - 回调接口
        
    /// </remarks>

        [ServiceContract(CallbackContract = typeof(IDuplexReentrantCallback))]
        
    public interface IDuplexReentrant
        
    {
            
    /// <summary>
            
    /// Hello
            
    /// </summary>
            
    /// <param name="name">名字</param>

            [OperationContract]
            
    void HelloDuplexReentrant(string name);
        }


        
    /// <summary>
        
    /// IDuplexReentrant回调接口
        
    /// </summary>

        public interface IDuplexReentrantCallback
        
    {
            
    /// <summary>
            
    /// Hello
            
    /// </summary>
            
    /// <param name="name"></param>

            [OperationContract]
            
    void HelloDuplexReentrantCallback(string name);
        }

    }


    DuplexReentrant.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using System.ServiceModel;

    namespace WCF.ServiceLib.Message
    {
        
    /// <summary>
        
    /// DuplexReentrant类 (演示ConcurrencyMode.Reentrant)
        
    /// </summary>
        
    /// <remarks>
        
    /// ConcurrencyMode - 获取或设置一个值,该值指示服务是支持单线程、多线程还是支持可重入调用。默认值为 System.ServiceModel.ConcurrencyMode.Single。
        
    /// Single - 服务实例是单线程的,且不接受可重入调用。
        
    /// Reentrant - 服务实例是单线程的,且接受可重入调用。
        
    /// Multiple - 服务实例是多线程的。
        
    /// </remarks>

        [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
        
    public class DuplexReentrant : IDuplexReentrant
        
    {
            
    /// <summary>
            
    /// Hello
            
    /// </summary>
            
    /// <param name="name">名字</param>

            public void HelloDuplexReentrant(string name)
            
    {
                
    // 声明回调接口
                IDuplexReentrantCallback callback = OperationContext.Current.GetCallbackChannel<IDuplexReentrantCallback>();

                
    // 调用回调接口中的方法
                callback.HelloDuplexReentrantCallback(name);
            }

        }

    }



    2、宿主
    DuplexReentrant.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using System.ServiceModel;

    namespace WCF.ServiceHost2.Message
    {
        
    /// <summary>
        
    /// host WCF.ServiceLib.Message.DuplexReentrant的类
        
    /// </summary>

        public class DuplexReentrant
        
    {
            
    /// <summary>
            
    /// 启动WCF.ServiceLib.Message.DuplexReentrant服务
            
    /// </summary>

            public void Launch()
            
    {
                
    using (ServiceHost host = new ServiceHost(typeof(WCF.ServiceLib.Message.DuplexReentrant)))
                
    {
                    host.Open();

                    Console.WriteLine(
    "服务已启动(WCF.ServiceLib.Message.DuplexReentrant)");
                    Console.WriteLine(
    "按<ENTER>停止服务");
                    Console.ReadLine();

                }

            }

        }

    }


    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
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using System.ServiceModel;
    using System.Windows.Forms;

    namespace Client2.Message
    {
        
    /// <summary>
        
    /// 演示Message.DuplexReentrant的类
        
    /// </summary>

        public class DuplexReentrant
        
    {
            
    /// <summary>
            
    /// Hello
            
    /// </summary>
            
    /// <param name="name">名字</param>

            public void HelloDulexReentrant(string name)
            
    {
                var ct 
    = new Client2.Message.ReentrantCallbackType();
                var ctx 
    = new InstanceContext(ct);

                var proxy 
    = new MessageSvc.DuplexReentrant.DuplexReentrantClient(ctx);

                proxy.HelloDuplexReentrant(name);
            }

        }

    }


    ReentrantCallbackType.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using System.Windows.Forms;

    namespace Client2.Message
    {
        
    /// <summary>
        
    /// 实现回调接口
        
    /// </summary>
        
    /// <remarks>
        
    /// CallbackBehavior - 在客户端应用程序中配置回调服务实现
        
    /// UseSynchronizationContext - 如果对服务的所有调用都必须在 System.Threading.SynchronizationContext 指定的线程上运行,则为 true;否则为false。默认值为 true。
        
    /// </remarks>

        [System.ServiceModel.CallbackBehavior(UseSynchronizationContext = false)]
        
    public class ReentrantCallbackType : MessageSvc.DuplexReentrant.IDuplexReentrantCallback
        
    {
            
    /// <summary>
            
    /// Hello
            
    /// </summary>
            
    /// <param name="name">名字</param>

            public void HelloDuplexReentrantCallback(string name)
            
    {
                MessageBox.Show(
    "Hello: " + name);
            }

        }

    }


    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
    [源码下载]
  • 相关阅读:
    Java代码:response压缩响应
    SpringBoot框架:第一章:基础配置和介绍
    asp.net 发送email
    .NET环境下水晶报表使用总结
    ASP.net(c#)生成条形码
    表格操作类(添加,删除,排序,上移,下移)
    NET email
    C#如何打印条形码EAN13码
    在asp.net中备份还原SQL Server数据库
    配置SQL2000数据库发送邮件
  • 原文地址:https://www.cnblogs.com/webabcd/p/1213019.html
Copyright © 2011-2022 走看看