化零为整WCF(13) - 并发控制(锁)(Mutex, Semaphore, Monitor, Lock, ThreadPool, Interlocked

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


化零为整WCF(13) - 并发控制(锁)(Mutex, Semaphore, Monitor, Lock, ThreadPool, Interlocked, ReaderWriterLock)


作者: webabcd


介绍
WCF(Windows Communication Foundation) - 并发控制:以ConcurrencyMode.Multiple并发模式及InstanceContextMode.Single实例模型为例(此时有并发问题),介绍如何做并发控制,即各种锁的使用(Mutex, Semaphore, Monitor, Lock, ThreadPool, Interlocked, ReaderWriterLock)


示例
1、服务
Enum.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
 
using System.ServiceModel; 
using System.Runtime.Serialization; 
 
namespace WCF.ServiceLib.ConcurrencyLock 

         /// <summary> 
         /// 锁 类型的枚举 
         /// </summary> 
        [DataContract] 
         public  enum LockType 
        { 
                 /// <summary> 
                 /// 不使用任何并发控制 
                 /// </summary> 
                [EnumMember] 
                None, 
                 /// <summary> 
                 /// Mutex 
                 /// </summary> 
                [EnumMember] 
                Mutex, 
                 /// <summary> 
                 /// Semaphore 
                 /// </summary> 
                [EnumMember] 
                Semaphore, 
                 /// <summary> 
                 /// Monitor 
                 /// </summary> 
                [EnumMember] 
                Monitor, 
                 /// <summary> 
                 /// Lock 
                 /// </summary> 
                [EnumMember] 
                Lock 
        } 
}
 
IHello.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
 
using System.ServiceModel; 
 
namespace WCF.ServiceLib.ConcurrencyLock 

         /// <summary> 
         /// 演示并发控制(锁)的接口 
         /// </summary> 
        [ServiceContract] 
         public  interface IHello 
        { 
                 /// <summary> 
                 /// 计数器 
                 /// </summary> 
                 /// <param name="lockType">锁的类型</param> 
                [OperationContract] 
                 void Counter(LockType lockType); 
 
                 /// <summary> 
                 /// 获取计数器被调用的结果 
                 /// </summary> 
                 /// <returns></returns> 
                [OperationContract] 
                 string GetResult(); 
 
                 /// <summary> 
                 /// 清空计数器和结果 
                 /// </summary> 
                [OperationContract] 
                 void CleanResult(); 
        } 
}
 
Hello.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
 
using System.ServiceModel; 
 
namespace WCF.ServiceLib.ConcurrencyLock 

         /// <summary> 
         /// 演示并发控制(锁)的接口 
         /// </summary> 
         /// <remarks> 
        /// ServiceBehavior - 指定服务协定实现的内部执行行为 
        /// 实例模型:单例;并发模式:多线程 
        /// 会有并发问题,通过 锁 来解决 
        /// </remarks> 

        [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] 
         public  class Hello : IHello 
        { 
                 private  int _counter; 
                 private  string _result; 
 
                 private System.Threading.Mutex _mutex =  new System.Threading.Mutex(); 
 
                 // 此构造函数初始化未命名的信号量。所有使用这类信号量的实例的线程都必须具有对该实例的引用。 
                 // 如果 initialCount 小于 maximumCount,则效果与当前线程调用了 WaitOne(maximumCount 减去 initialCount)次相同。如果不想为创建信号量的线程保留任何入口,请对 maximumCount 和 initialCount 使用相同的数值。 
                 private System.Threading.Semaphore _semaphore =  new System.Threading.Semaphore(1, 1); 
 
                 private  static  readonly  object objLock =  new  object(); 
 
 
                 /// <summary> 
                 /// 计数器 
                 /// </summary> 
                 /// <returns></returns> 
                 public  void Counter(LockType lockType) 
                { 
                         switch (lockType) 
                        { 
                                 case LockType.None: 
                                        ExecuteNone(); 
                                         break
                                 case LockType.Mutex: 
                                        ExecuteMutex(); 
                                         break
                                 case LockType.Semaphore: 
                                        ExecuteSemaphore(); 
                                         break
                                 case LockType.Monitor: 
                                        ExecuteMonitor(); 
                                         break
                                 case LockType.Lock: 
                                        ExecuteLock(); 
                                         break
                        } 
                } 
 
                 /// <summary> 
                 /// 获取计数器被调用的结果 
                 /// </summary> 
                 /// <returns></returns> 
                 public  string GetResult() 
                { 
                         return _result; 
                } 
 
                 /// <summary> 
                 /// 清空计数器和结果 
                 /// </summary> 
                 public  void CleanResult() 
                { 
                        _result = ""; 
                        _counter = 0; 
                } 
 
                 /// <summary> 
                 /// 循环调用技术器,以模拟并发 
                 /// 结果中,出现重复计数,则有并发问题,反之,则无并发问题 
                 /// </summary> 
                 private  void CircleCounter() 
                { 
                         for ( int i = 0; i < 10; i++) 
                        { 
                                var counter = _counter; 
 
                                 // 停20毫秒,以模拟并发 
                                System.Threading.Thread.Sleep(20); 
 
                                _counter = ++counter; 
 
                                 // 保存计数结果 
                                _result += _counter +  "|"
                        } 
                } 
 
                 /// <summary> 
                 /// 不使用任何并发控制 
                 /// </summary> 
                 private  void ExecuteNone() 
                { 
                        CircleCounter(); 
                } 
 
                 /// <summary> 
                 /// Mutex的实现 
                 /// </summary> 
                 private  void ExecuteMutex() 
                { 
                         try 
                        { 
                                _mutex.WaitOne(); 
 
                                CircleCounter(); 
                        } 
                         finally 
                        { 
                                _mutex.ReleaseMutex(); 
                        } 
                } 
 
                 /// <summary> 
                 /// Semaphore的实现 
                 /// </summary> 
                 private  void ExecuteSemaphore() 
                { 
                         try 
                        { 
                                _semaphore.WaitOne(); 
 
                                CircleCounter(); 
                        } 
                         finally 
                        { 
                                _semaphore.Release(); 
                        } 
                } 
 
                 /// <summary> 
                 /// Monitor的实现 
                 /// </summary> 
                 private  void ExecuteMonitor() 
                { 
                         try 
                        { 
                                System.Threading.Monitor.Enter( this); 
 
                                CircleCounter(); 
                        } 
                         finally 
                        { 
                                System.Threading.Monitor.Exit( this); 
                        } 
                } 
 
                 /// <summary> 
                 /// Lock的实现 
                 /// </summary> 
                 private  void ExecuteLock() 
                { 
                         try 
                        { 
                                 lock (objLock) 
                                { 
                                        CircleCounter(); 
                                } 
                        } 
                         finally 
                        { 
 
                        } 
                } 
        } 
}
 
 
2、宿主
Hello.svc
<%@ ServiceHost Language="C#" Debug="true" Service="WCF.ServiceLib.ConcurrencyLock.Hello" %>
 

Web.config
<?xml version="1.0"?> 
<configuration> 
        <system.serviceModel> 
                <behaviors> 
                        <serviceBehaviors> 
                                <behavior name="ConcurrencyLockBehavior"> 
                                        <!--httpGetEnabled - 指示是否发布服务元数据以便使用 HTTP/GET 请求进行检索,如果发布 WSDL,则为 true,否则为 false,默认值为 false--> 
                                        <serviceMetadata httpGetEnabled="true" /> 
                                        <serviceDebug includeExceptionDetailInFaults="true"/> 
                                </behavior> 
                        </serviceBehaviors> 
                </behaviors> 
                <services> 
                        <!--name - 提供服务的类名--> 
                        <!--behaviorConfiguration - 指定相关的行为配置--> 
                        <service name="WCF.ServiceLib.ConcurrencyLock.Hello" behaviorConfiguration="ConcurrencyLockBehavior"> 
                                <!--address - 服务地址--> 
                                <!--binding - 通信方式--> 
                                <!--contract - 服务契约--> 
                                <endpoint address="" binding="basicHttpBinding" contract="WCF.ServiceLib.ConcurrencyLock.IHello" /> 
                        </service> 
                </services> 
        </system.serviceModel> 
</configuration>
 
 

3、客户端
Hello.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Hello.aspx.cs" 
        Inherits="ConcurrencyLock_Hello" Title="并发控制(锁)(Mutex, Semaphore, Monitor, Lock, ThreadPool, Interlocked, ReaderWriterLock)" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server"> 
</asp:Content> 
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server"> 
        <p> 
                <asp:Button ID="btnCleanResult" runat="server" Text="清空结果" OnClick="btnCleanResult_Click" /> 
                  
                <asp:Button ID="btnHelloNone" runat="server" Text="HelloNone" OnCommand="btn_Command" 
                        CommandName="None" /> 
                  
                <asp:Button ID="btnHelloMutex" runat="server" Text="HelloMutex" OnCommand="btn_Command" 
                        CommandName="Mutex" /> 
                  
                <asp:Button ID="btnHelloSemaphore" runat="server" Text="HelloSemaphore" OnCommand="btn_Command" 
                        CommandName="Semaphore" /> 
                  
                <asp:Button ID="btnHelloMonitor" runat="server" Text="HelloMonitor" OnCommand="btn_Command" 
                        CommandName="Monitor" /> 
                  
                <asp:Button ID="btnHelloLock" runat="server" Text="HelloLock" OnCommand="btn_Command" 
                        CommandName="Lock" /> 
                <br /> 
                <ul> 
                        <li>None:不使用并发控制(有并发问题,会出现重复的计数)</li> 
                        <li>其他:使用相关的并发控制(无并发问题,不会出现重复的计数)</li> 
                </ul> 
        </p> 
        <div> 
                <asp:TextBox ID="txtResult" runat="server" TextMode="MultiLine" Style="width: 98%; 
                        height: 200px" /> 
        </div> 
        <div> 
                <ul> 
                        <li>Mutex - 提供对资源的独占访问</li> 
                        <li>Semaphore - 限制可同时访问某一资源或资源池的线程数</li> 
                        <li>Monitor - 提供同步访问对象的机制</li> 
                        <li>Lock - 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁</li> 
                        <li>ThreadPool - 提供一个线程池,该线程池可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器</li> 
                        <li>Interlocked - 为多个线程共享的变量提供原子操作</li> 
                        <li>ReaderWriterLock - 定义支持单个写线程和多个读线程的锁</li> 
                </ul> 
        </div> 
</asp:Content>
 
Hello.aspx.cs
using System; 
using System.Collections; 
using System.Configuration; 
using System.Data; 
using System.Linq; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Xml.Linq; 
 
using System.Threading; 
 
public partial  class ConcurrencyLock_Hello : System.Web.UI.Page 

         protected  void Page_Load( object sender, EventArgs e) 
        { 
 
        } 
 
         protected  void btn_Command( object sender, CommandEventArgs e) 
        { 
                 // 线程1 
                var thread1 =  new Thread( new ParameterizedThreadStart(Do)); 
                thread1.Start(e.CommandName); 
 
                 // 线程2 
                var thread2 =  new Thread( new ParameterizedThreadStart(Do)); 
                thread2.Start(e.CommandName); 
 
                 for ( int i = 0; i < 100; i++) 
                { 
                        Thread.Sleep(100); 
 
                         if (thread1.ThreadState == ThreadState.Stopped && thread2.ThreadState == ThreadState.Stopped) 
                        { 
                                 // 返回服务端的技术器的调用结果 
                                var proxy =  new ConcurrencyLockSvc.HelloClient(); 
 
                                txtResult.Text = proxy.GetResult(); 
 
                                proxy.Close(); 
 
                                 break
                        } 
                } 
        } 
 
         private  void Do( object commandName) 
        { 
                ConcurrencyLockSvc.LockType lockType = (ConcurrencyLockSvc.LockType)Enum.Parse( typeof(ConcurrencyLockSvc.LockType), ( string)commandName); 
 
                 // 调用服务端技术器 
                 using (var proxy =  new ConcurrencyLockSvc.HelloClient()) 
                { 
                        proxy.Counter(lockType); 
                } 
        } 
 
         protected  void btnCleanResult_Click( object sender, EventArgs e) 
        { 
                 // 清空计数器和结果 
                 using (var proxy =  new ConcurrencyLockSvc.HelloClient()) 
                { 
                        proxy.CleanResult(); 
                } 
 
                txtResult.Text = ""; 
        } 
}
 
Web.config
<?xml version="1.0"?> 
<configuration> 
        <system.serviceModel> 
                <client> 
                        <!--address - 服务地址--> 
                        <!--binding - 通信方式--> 
                        <!--contract - 服务契约--> 
                        <endpoint address="http://localhost:3502/ServiceHost/ConcurrencyLock/Hello.svc" binding="basicHttpBinding" contract="ConcurrencyLockSvc.IHello" /> 
                </client> 
        </system.serviceModel> 
</configuration>
 
 
运行结果:
单击"HelloNone"按钮:不使用并发控制(有并发问题,会出现重复的计数)
单击"HelloMutex", "HelloSemaphore", "HelloMonitor", "HelloLock"按钮:使用相应的并发控制(无并发问题,不会出现重复的计数)


OK
[源码下载]



     本文转自webabcd 51CTO博客,原文链接: http://blog.51cto.com/webabcd/344157 ,如需转载请自行联系原作者

相关文章
|
前端开发
WCF更新服务引用报错的原因之一
WCF更新服务引用报错的原因之一
|
C# 数据安全/隐私保护
c#如何创建WCF服务到发布(SqlServer版已经验证)
c#如何创建WCF服务到发布(SqlServer版已经验证)
74 0
|
安全 数据库连接 数据库
WCF服务创建到发布(SqlServer版)
在本示例开始之前,让我们先来了解一下什么是wcf? wcf有哪些特点? wcf是一个面向服务编程的综合分层架构。该架构的项层为服务模型层。 使用户用最少的时间和精力建立自己的软件产品和外界通信的模型。它使得开发者能够建立一个跨平台的安全、可信赖、事务性的解决方案。且能与已有系统兼容写作。 简单概括就是:一组数据通信的应用程序开发接口。
113 0