【亚洲必赢官网】创立平安的栈,线程基础

   
在C#中,用于存款和储蓄的组织较多,如:DataTable,DataSet,List,Dictionary,Stack等结构,各个组织选取的贮存的法子存在差别,作用也自然各有利害。今后介绍壹种后进先出的数据结构。

C#创造安全的栈(Stack)存款和储蓄结构,

   
在C#中,用于存款和储蓄的布局较多,如:DataTable,DataSet,List,Dictionary,Stack等组织,各个组织选拔的贮存的方法存在差异,效用也决然各有利害。未来牵线壹种后进先出的数据结构。

 
 聊到存储结构,大家在类型中运用的较多。对于Task存款和储蓄结构,栈与队列是接近的组织,在采纳的时候利用不一致的章程。C#中栈(Stack)是编写翻译时期就分配好的内部存款和储蓄器空间,因而你的代码中必须就栈的轻重有强烈的概念;堆是程序运营期间动态分配的内部存款和储蓄器空间,你能够依据程序的运作情形分明要分配的堆内部存款和储蓄器的分寸。

   
在C#中,栈常常保存着大家代码实施的步子。C#中的引用类型存款和储蓄在栈中,在程序运行的时候,每一个线程(Thread)都会维护2个要好的专属线程仓库。当二个办法被调用的时候,主线程先导在所属程序集的元数据中,查找被调用方法,然后经过JIT即时编写翻译并把结果(一般是本地CPU指令)放在栈顶。CPU通过总线从栈顶取指令,驱动程序以试行下去。

   
以上对栈那一个数据结构举行了三个简约的牵线,今后看一下C#完成栈结构的平底方法:

   /// <summary>
    /// 初始化 <see cref="T:System.Collections.Generic.Stack`1"/> 类的新实例,该实例为空并且具有默认初始容量。
    /// </summary>
    [__DynamicallyInvokable]
    public Stack();
    /// <summary>
    /// 初始化 <see cref="T:System.Collections.Generic.Stack`1"/> 类的新实例,该实例为空,具有指定的初始容量或默认的初始容量(其中较大的一个)。
    /// </summary>
    /// <param name="capacity"><see cref="T:System.Collections.Generic.Stack`1"/> 可包含的初始元素数。</param><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="capacity"/> is less than zero.</exception>
    [__DynamicallyInvokable]
    public Stack(int capacity);
    /// <summary>
    /// 初始化 <see cref="T:System.Collections.Generic.Stack`1"/> 类的新实例,该实例包含从指定集合复制的元素并且具有足够的容量来容纳所复制的元素。
    /// </summary>
    /// <param name="collection">从中复制元素的集合。</param><exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is null.</exception>
    [__DynamicallyInvokable]
    public Stack(IEnumerable<T> collection);

 
 以上是对stack的片段方法的牵线,由于在操作数据存款和储蓄的同时,会考虑到线程的安全性。

 
 进度作为操作系统试行顺序的骨干单位,具备应用程序的财富,进度包涵线程,进度的能源被线程共享,线程不富有资源。线程分为前台线程和后台线程,通过Thread类新建线程默以为前台线程。当全数前台线程关闭时,全部的后台线程也会被直接终止,不会抛出极度。

    接下去看一下ReaderWriterLockSlim类:

/// <summary>
  /// 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问。
  /// </summary>
  [__DynamicallyInvokable]
  [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true, Synchronization = true)]
  [HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
  public class ReaderWriterLockSlim : IDisposable
  {
    /// <summary>
    /// 使用默认属性值初始化 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 类的新实例。
    /// </summary>
    [__DynamicallyInvokable]
    public ReaderWriterLockSlim();
    /// <summary>
    /// 在指定锁定递归策略的情况下初始化 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 类的新实例。
    /// </summary>
    /// <param name="recursionPolicy">枚举值之一,用于指定锁定递归策略。</param>
    [__DynamicallyInvokable]
    public ReaderWriterLockSlim(LockRecursionPolicy recursionPolicy);
    /// <summary>
    /// 尝试进入读取模式锁定状态。
    /// </summary>
    /// <exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入读取的模式。- 或 -当它已经包含写入锁时,当前线程可能不会获取读的锁定。- 或 -递归数将超出该计数器的容量。此限制是很大的应用程序应永远不会遇到它。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public void EnterReadLock();
    /// <summary>
    /// 尝试进入读取模式锁定状态,可以选择超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入读取模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="timeout">等待的间隔;或为 -1 毫秒,表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="timeout"/> 为负数,但它不等于-1 毫秒为单位),这是唯一允许的值为负。- 或 -值 <paramref name="timeout"/> 大于 <see cref="F:System.Int32.MaxValue"/> 毫秒为单位)。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterReadLock(TimeSpan timeout);
    /// <summary>
    /// 尝试进入读取模式锁定状态,可以选择整数超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入读取模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="millisecondsTimeout">等待的毫秒数,或为 -1 (<see cref="F:System.Threading.Timeout.Infinite"/>),表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="millisecondsTimeout"/> 为负数,但它不是等于 <see cref="F:System.Threading.Timeout.Infinite"/> (-1),这是唯一允许的值为负。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterReadLock(int millisecondsTimeout);
    /// <summary>
    /// 尝试进入写入模式锁定状态。
    /// </summary>
    /// <exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已在任何模式下进入该锁。- 或 -当前线程已进入读取的模式,因此尝试进入锁定状态写模式,则会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public void EnterWriteLock();
    /// <summary>
    /// 尝试进入写入模式锁定状态,可以选择超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入写入模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="timeout">等待的间隔;或为 -1 毫秒,表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入写入模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="timeout"/> 为负数,但它不等于-1 毫秒为单位),这是唯一允许的值为负。- 或 -值 <paramref name="timeout"/> 大于 <see cref="F:System.Int32.MaxValue"/> 毫秒为单位)。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterWriteLock(TimeSpan timeout);
    /// <summary>
    /// 尝试进入写入模式锁定状态,可以选择超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入写入模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="millisecondsTimeout">等待的毫秒数,或为 -1 (<see cref="F:System.Threading.Timeout.Infinite"/>),表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入写入模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="millisecondsTimeout"/> 为负数,但它不是等于 <see cref="F:System.Threading.Timeout.Infinite"/> (-1),这是唯一允许的值为负。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterWriteLock(int millisecondsTimeout);
    /// <summary>
    /// 尝试进入可升级模式锁定状态。
    /// </summary>
    /// <exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已在任何模式下进入该锁。- 或 -当前线程已进入读取的模式,因此尝试进入可升级模式将有死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public void EnterUpgradeableReadLock();
    /// <summary>
    /// 尝试进入可升级模式锁定状态,可以选择超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入可升级模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="timeout">等待的间隔;或为 -1 毫秒,表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入可升级模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="timeout"/> 为负数,但它不等于-1 毫秒为单位),这是唯一允许的值为负。- 或 -值 <paramref name="timeout"/> 大于 <see cref="F:System.Int32.MaxValue"/> 毫秒为单位)。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterUpgradeableReadLock(TimeSpan timeout);
    /// <summary>
    /// 尝试进入可升级模式锁定状态,可以选择超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入可升级模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="millisecondsTimeout">等待的毫秒数,或为 -1 (<see cref="F:System.Threading.Timeout.Infinite"/>),表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入可升级模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="millisecondsTimeout"/> 为负数,但它不是等于 <see cref="F:System.Threading.Timeout.Infinite"/> (-1),这是唯一允许的值为负。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterUpgradeableReadLock(int millisecondsTimeout);
    /// <summary>
    /// 减少读取模式的递归计数,并在生成的计数为 0(零)时退出读取模式。
    /// </summary>
    /// <exception cref="T:System.Threading.SynchronizationLockException">在读取模式中,当前线程不已进入该锁。</exception>
    [__DynamicallyInvokable]
    public void ExitReadLock();
    /// <summary>
    /// 减少写入模式的递归计数,并在生成的计数为 0(零)时退出写入模式。
    /// </summary>
    /// <exception cref="T:System.Threading.SynchronizationLockException">当前线程不已进入写入模式的锁定。</exception>
    [__DynamicallyInvokable]
    public void ExitWriteLock();
    /// <summary>
    /// 减少可升级模式的递归计数,并在生成的计数为 0(零)时退出可升级模式。
    /// </summary>
    /// <exception cref="T:System.Threading.SynchronizationLockException">当前线程不已进入可升级模式的锁定。</exception>
    [__DynamicallyInvokable]
    public void ExitUpgradeableReadLock();
    /// <summary>
    /// 释放 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 类的当前实例所使用的所有资源。
    /// </summary>
    /// <exception cref="T:System.Threading.SynchronizationLockException"><see cref="P:System.Threading.ReaderWriterLockSlim.WaitingReadCount"/> 是大于零。- 或 -<see cref="P:System.Threading.ReaderWriterLockSlim.WaitingUpgradeCount"/> 是大于零。- 或 -<see cref="P:System.Threading.ReaderWriterLockSlim.WaitingWriteCount"/> 是大于零。</exception><filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public void Dispose();
    /// <summary>
    /// 获取一个值,该值指示当前线程是否已进入读取模式的锁定状态。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程已进入读取模式,则为 true;否则为 false。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public bool IsReadLockHeld { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取一个值,该值指示当前线程是否已进入可升级模式的锁定状态。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程已进入可升级模式,则为 true;否则为 false。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public bool IsUpgradeableReadLockHeld { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取一个值,该值指示当前线程是否已进入写入模式的锁定状态。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程已进入写入模式,则为 true;否则为 false。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public bool IsWriteLockHeld { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取一个值,该值指示当前 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象的递归策略。
    /// </summary>
    /// 
    /// <returns>
    /// 枚举值之一,用于指定锁定递归策略。
    /// </returns>
    [__DynamicallyInvokable]
    public LockRecursionPolicy RecursionPolicy { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取已进入读取模式锁定状态的独有线程的总数。
    /// </summary>
    /// 
    /// <returns>
    /// 已进入读取模式锁定状态的独有线程的数量。
    /// </returns>
    [__DynamicallyInvokable]
    public int CurrentReadCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取当前线程进入读取模式锁定状态的次数,用于指示递归。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程未进入读取模式,则为 0(零);如果线程已进入读取模式但却不是以递归方式进入的,则为 1;或者如果线程已经以递归方式进入锁定模式 n - 1 次,则为 n。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int RecursiveReadCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取当前线程进入可升级模式锁定状态的次数,用于指示递归。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程没有进入可升级模式,则为 0;如果线程已进入可升级模式却不是以递归方式进入的,则为 1;或者如果线程已经以递归方式进入可升级模式 n - 1 次,则为 n。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int RecursiveUpgradeCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取当前线程进入写入模式锁定状态的次数,用于指示递归。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程没有进入写入模式,则为 0;如果线程已进入写入模式却不是以递归方式进入的,则为 1;或者如果线程已经以递归方式进入写入模式 n - 1 次,则为 n。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int RecursiveWriteCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取等待进入读取模式锁定状态的线程总数。
    /// </summary>
    /// 
    /// <returns>
    /// 等待进入读取模式的线程总数。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int WaitingReadCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取等待进入可升级模式锁定状态的线程总数。
    /// </summary>
    /// 
    /// <returns>
    /// 等待进入可升级模式的线程总数。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int WaitingUpgradeCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取等待进入写入模式锁定状态的线程总数。
    /// </summary>
    /// 
    /// <returns>
    /// 等待进入写入模式的线程总数。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int WaitingWriteCount { [__DynamicallyInvokable] get; }
  }

     以上是对Stack和线程的连带文化的浅述,未来介绍一下线程安全的Stack:

 

     /// <summary>
    /// 表示对象的后进先出线程安全集合(栈结构)
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class TStack<T> : IEnumerable<T>, ICollection
    {
        /// <summary>
        /// 内部堆栈
        /// </summary>
        private readonly Stack<T> _mStack;

        /// <summary>
        /// 锁访问堆栈(用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问。)
        /// </summary>
        private readonly ReaderWriterLockSlim _lockStack = new ReaderWriterLockSlim();

        /// <summary>
        /// 仅用于SyncRoot属性
        /// </summary>
        private readonly object _objSyncRoot = new object();

        // Variables
        /// <summary>
        /// 初始化一个新的实例 <see cref="TStack{T}"/> class.
        /// </summary>
        public TStack()
        {
            _mStack = new Stack<T>();
        }

        /// <summary>
        /// 初始化一个新的实例 <see cref="TStack{T}"/> class.
        /// </summary>
        /// <param name="col">
        /// 开始集合
        /// </param>
        public TStack(IEnumerable<T> col)
        {
            _mStack = new Stack<T>(col);
        }

        // Init
        /// <summary>
        /// 获取枚举器
        /// </summary>
        public IEnumerator<T> GetEnumerator()
        {
            Stack<T> localStack = null;

            // 初始化枚举器
            _lockStack.PerformUsingReadLock(() =>
            {
                // 创建一个m_tlist副本
                localStack = new Stack<T>(_mStack);
            });

            // 获取枚举器
            foreach (T item in localStack)
                yield return item;
        }


        /// <summary>
        /// 获取枚举器
        /// </summary>
        IEnumerator IEnumerable.GetEnumerator()
        {
            Stack<T> localStack = null;

            // 初始化枚举器
            _lockStack.PerformUsingReadLock(() =>
            {
                // 创建一个m_TList的副本
                localStack = new Stack<T>(_mStack);
            });

            // 获取枚举器
            foreach (T item in localStack)
                yield return item;
        }


        /// <summary>
        /// 复制到一个数组
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        public void CopyTo(Array array, int index)
        {
            _lockStack.PerformUsingReadLock(() => _mStack.ToArray().CopyTo(array, index));
        }

        /// <summary>
        ///堆栈中的项目数
        /// </summary>
        public int Count
        {
            get
            {
                return _lockStack.PerformUsingReadLock(() => _mStack.Count);
            }
        }

        /// <summary>
        /// 总为真
        /// </summary>
        public bool IsSynchronized
        {
            get { return true; }
        }

        /// <summary>
        ///同步根
        /// </summary>
        public object SyncRoot
        {
            get { return _objSyncRoot; }
        }


        /// <summary>
        ///清除集合
        /// </summary>
        public void Clear()
        {
            _lockStack.PerformUsingWriteLock(() => _mStack.Clear());
        }

        // Clear
        /// <summary>
        ///如果项目在堆栈中,则为true
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Contains(T item)
        {
            return _lockStack.PerformUsingReadLock(() => _mStack.Contains(item));
        }

        // 包含
        /// <summary>
        /// 返回堆栈中的顶部项,而不从堆栈中删除它
        /// </summary>
        /// <returns></returns>
        public T Peek()
        {
            return _lockStack.PerformUsingReadLock(() => _mStack.Peek());
        }

        // Peek
        /// <summary>
        ///删除并返回堆栈中的顶部项目
        /// </summary>
        /// <returns></returns>
        public T Pop()
        {
            return _lockStack.PerformUsingWriteLock(() => _mStack.Pop());
        }

        // Pop
        /// <summary>
        /// 将一个项目插入堆栈
        /// </summary>
        /// <param name="item"></param>
        public void Push(T item)
        {
            _lockStack.PerformUsingWriteLock(() => _mStack.Push(item));
        }

        // Push
        /// <summary>
        ///将堆栈转换为数组
        /// </summary>
        /// <returns></returns>
        public T[] ToArray()
        {
            return _lockStack.PerformUsingReadLock(() => _mStack.ToArray());
        }

        // ToArray
        /// <summary>
        /// 将容量设置为堆栈中实际的元素数量
        /// </summary>
        public void TrimExcess()
        {
            _lockStack.PerformUsingWriteLock(() => _mStack.TrimExcess());
        }
    }

    以上的操作方法承接了IEnumerable<T>,
ICollection七个接口。有意思味的,能够对IEnumerable<T>,
ICollection八个接口举办细心的问询。

 

在C#中,用于存款和储蓄的结构较多,如:DataTable,DataSet,List,Dictionary,Stack等结构,各个组织采纳的贮存的方…

如今项目中要用到线程相关的学问,所以先看了本书前面线程的始末,并做了一些总括。

 
 说到存款和储蓄结构,大家在等级次序中选用的较多。对于Task存款和储蓄结构,栈与队列是类似的组织,在动用的时候利用不一致的不二等秘书籍。C#中栈(Stack)是编写翻译期间就分配好的内部存款和储蓄器空间,由此你的代码中务必就栈的轻重有明显的定义;堆是程序运行时期动态分配的内存空间,你可以依照程序的周转情状鲜明要分配的堆内部存款和储蓄器的尺寸。

【亚洲必赢官网】创立平安的栈,线程基础。首要内容:

   
在C#中,栈平常保存着大家代码实施的步子。C#中的引用类型存款和储蓄在栈中,在程序运转的时候,各类线程(Thread)都会维护三个协和的专属线程仓库。当1个措施被调用的时候,主线程发轫在所属程序集的元数据中,查找被调用方法,然后通过JIT即时编写翻译并把结果(一般是当地CPU指令)放在栈顶。CPU通过总线从栈顶取指令,驱动程序以实行下去。

  • 线程费用
  • 线程的创建
  • 前台和后台线程 

   
以上对栈那些数据结构实行了一个简练的介绍,未来看一下C#贯彻栈结构的平底方法:

1. 线程花费

   /// <summary>
    /// 初始化 <see cref="T:System.Collections.Generic.Stack`1"/> 类的新实例,该实例为空并且具有默认初始容量。
    /// </summary>
    [__DynamicallyInvokable]
    public Stack();
    /// <summary>
    /// 初始化 <see cref="T:System.Collections.Generic.Stack`1"/> 类的新实例,该实例为空,具有指定的初始容量或默认的初始容量(其中较大的一个)。
    /// </summary>
    /// <param name="capacity"><see cref="T:System.Collections.Generic.Stack`1"/> 可包含的初始元素数。</param><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="capacity"/> is less than zero.</exception>
    [__DynamicallyInvokable]
    public Stack(int capacity);
    /// <summary>
    /// 初始化 <see cref="T:System.Collections.Generic.Stack`1"/> 类的新实例,该实例包含从指定集合复制的元素并且具有足够的容量来容纳所复制的元素。
    /// </summary>
    /// <param name="collection">从中复制元素的集合。</param><exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is null.</exception>
    [__DynamicallyInvokable]
    public Stack(IEnumerable<T> collection);

1.一 线程的概念

只要未有线程,当应用程序出现死循环时,应用程序所在的进程会直接占领CPU,导致”死机”的场景。

那么线程是何许防止那种”死机”现象,使得应用程序能更加好的响应用户的乞求呢?

Windows系统中引进了线程的定义后,每一种进程至少有1个专有线程(也正是这些历程专用的CPU),

系统已线程为单位分配CPU时间片,假如二个应用程序进入Infiniti循环,那么它的专有线程会”死机”。

只是任何进程的专无线程不会”死机”,所以系统不会告1段落响应,也不汇合世”死机”。

 

 
 以上是对stack的有的方法的介绍,由于在操作数据存款和储蓄的同时,会设想到线程的安全性。

1.② 线程的构造

线程还足以追加程序的并发性,对于多CPU的场地,能够拉长度序的特性,但还要也会使程序更为复杂。

对峙于经过,线程确实是很”轻量”,不过假设在经过中蛮目的加码线程,一样会对系统财富带来一点都不小的担负。

上边来探望Windows系统中线程的开荒有多大?

线程首要含有以下多少个成分:

线程内查对象。x八六(约700字节),x6四(约1240字节),IA64(约2500字节)

带有线程的性质及上下文音讯,其中上下文新闻包括当前CPU的寄存器信息等。

当CPU切换线程时,需求将近来线程的寄存器音讯保存到上下文中,同时将新线程的上下文复制到CPU寄存器中。

 

线程意况块。x捌六和x6肆(4KB),IA6四(捌KB)

在用户格局中分红,包蕴线程的万分管理链首,线程本地存款和储蓄的数据,GDI和OpenGL图形使用的局地数据结构。

 

用户情势栈。1MB

仓储方法的实参和一些变量,以及重临的地点。

 

水源形式栈。32bit(12KB),6四bit(24KB)

与基础交互时的多少(比方传递给基础的参数)。

 

DLL的attach和detach通知。

创设线程时,调用当前历程加载的享有DLL的DllMain方法,并传递DLL_THREAD_ATTACH标志。

终止线程时,调用当前经过加载的装有DLL的DllMain方法,并传递DLL_THREAD_DETACH标志。

 

经过地点的剖析,大家开掘各样线程至少占用1MB的内存,能源的损耗并相当大,全体要理性的运用它们,只在必须求用线程的地点接纳它们。

 

 
 进度作为操作系统实践顺序的主干单位,具有应用程序的能源,进度包罗线程,进度的财富被线程共享,线程不富有能源。线程分为前台线程和后台线程,通过Thread类新建线程默许为前台线程。当全体前台线程关闭时,全部的后台线程也会被直接终止,不会抛出分外。

2. 线程的创导

C#中利用线程非常轻便,利用System.Threading.Tread类就可以。

亚洲必赢官网,Thread的构造函数的参数有贰种委托:

(一) 1种是有参数的委托

public delegate void ParameterizedThreadStart(object obj);

(2) 一种是无参数的嘱托

public delegate void ThreadStart()

 

事举例下:

using System;
using System.Threading;

class CLRviaCSharp_17
{
    static void Main(string[] args)
    {
        Console.WriteLine("This is Main Thread!");

        // 有参数的委托
        Thread t1 = new Thread(SubThreadMethod);
        t1.Start("sub thread parameter");

        // 无参数的委托
        Thread t2 = new Thread(SubThreadMethod2);
        t2.Start();

        Thread.Sleep(4000);
        Console.WriteLine("Main Thread complete!");
        Console.ReadKey(true);
    }

    private static void SubThreadMethod(object param)
    {
        Console.WriteLine("This is Sub Thread with parameter : {0}", param);
        Thread.Sleep(1000);
    }

    private static void SubThreadMethod2()
    {
        Console.WriteLine("This is Sub Thread without parameter!");
        Thread.Sleep(1000);
    }
}

 

其间Thread t1和t2的推行各种是不定的,只怕t一先举行,也恐怕t二先执行。

 

    接下去看一下ReaderWriterLockSlim类:

三. 前台和后台线程

就算如此近来3个CLCR-V中的线程直接对应于一个Windows中的线程,不过随后是有相当的大希望分离的。

而我们目前在C#中利用的线程都是CL奔驰G级线程。

CLRAV四线程分为前台线程和后台线程贰种。上边例子中一向开立的线程默以为前台线程,用线程池创设的线程默感觉后台线程。

咱俩应尽量防止使用前台线程,多采纳后台线程。

由来在于:一个历程唯有当它的具有前台线程全体截止后才会终止,借使有3个前台线程陷入死循环,那么那些进程就不能活动结束。

上边来看我们作证的事例:

率先验证前台线程,新建玖九个前台线程,每一个线程Sleep
5秒,主线程在新建完91七个线程后就得了。

using System.Threading;

class CLRviaCSharp_17
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 100; i++)
        {
            Thread t = new Thread(ThreadMethod);
            t.Start();
        }
    }

    private static void ThreadMethod()
    {
        Thread.Sleep(5000);
    }
}

程序运营后并从未马上终止,而是等了五秒才甘休。(原因在于有前台线程没安息,进度不能自动终止)

 

再作证后台进度,代码差不多,只是在新建线程后把线程的IsBackground本性改为True

using System.Threading;

class CLRviaCSharp_17
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 100; i++)
        {
            Thread t = new Thread(ThreadMethod);
            // 将新建的线程标记为后台线程
            t.IsBackground = true;
            t.Start();
        }
    }

    private static void ThreadMethod()
    {
        Thread.Sleep(5000);
    }
}

程序运转后随即终止,未有等后台线程五秒。(原因在于全部前台线程已告壹段落,后台进度也自动截止了)

/// <summary>
  /// 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问。
  /// </summary>
  [__DynamicallyInvokable]
  [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true, Synchronization = true)]
  [HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
  public class ReaderWriterLockSlim : IDisposable
  {
    /// <summary>
    /// 使用默认属性值初始化 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 类的新实例。
    /// </summary>
    [__DynamicallyInvokable]
    public ReaderWriterLockSlim();
    /// <summary>
    /// 在指定锁定递归策略的情况下初始化 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 类的新实例。
    /// </summary>
    /// <param name="recursionPolicy">枚举值之一,用于指定锁定递归策略。</param>
    [__DynamicallyInvokable]
    public ReaderWriterLockSlim(LockRecursionPolicy recursionPolicy);
    /// <summary>
    /// 尝试进入读取模式锁定状态。
    /// </summary>
    /// <exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入读取的模式。- 或 -当它已经包含写入锁时,当前线程可能不会获取读的锁定。- 或 -递归数将超出该计数器的容量。此限制是很大的应用程序应永远不会遇到它。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public void EnterReadLock();
    /// <summary>
    /// 尝试进入读取模式锁定状态,可以选择超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入读取模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="timeout">等待的间隔;或为 -1 毫秒,表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="timeout"/> 为负数,但它不等于-1 毫秒为单位),这是唯一允许的值为负。- 或 -值 <paramref name="timeout"/> 大于 <see cref="F:System.Int32.MaxValue"/> 毫秒为单位)。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterReadLock(TimeSpan timeout);
    /// <summary>
    /// 尝试进入读取模式锁定状态,可以选择整数超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入读取模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="millisecondsTimeout">等待的毫秒数,或为 -1 (<see cref="F:System.Threading.Timeout.Infinite"/>),表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="millisecondsTimeout"/> 为负数,但它不是等于 <see cref="F:System.Threading.Timeout.Infinite"/> (-1),这是唯一允许的值为负。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterReadLock(int millisecondsTimeout);
    /// <summary>
    /// 尝试进入写入模式锁定状态。
    /// </summary>
    /// <exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已在任何模式下进入该锁。- 或 -当前线程已进入读取的模式,因此尝试进入锁定状态写模式,则会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public void EnterWriteLock();
    /// <summary>
    /// 尝试进入写入模式锁定状态,可以选择超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入写入模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="timeout">等待的间隔;或为 -1 毫秒,表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入写入模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="timeout"/> 为负数,但它不等于-1 毫秒为单位),这是唯一允许的值为负。- 或 -值 <paramref name="timeout"/> 大于 <see cref="F:System.Int32.MaxValue"/> 毫秒为单位)。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterWriteLock(TimeSpan timeout);
    /// <summary>
    /// 尝试进入写入模式锁定状态,可以选择超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入写入模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="millisecondsTimeout">等待的毫秒数,或为 -1 (<see cref="F:System.Threading.Timeout.Infinite"/>),表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入写入模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="millisecondsTimeout"/> 为负数,但它不是等于 <see cref="F:System.Threading.Timeout.Infinite"/> (-1),这是唯一允许的值为负。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterWriteLock(int millisecondsTimeout);
    /// <summary>
    /// 尝试进入可升级模式锁定状态。
    /// </summary>
    /// <exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已在任何模式下进入该锁。- 或 -当前线程已进入读取的模式,因此尝试进入可升级模式将有死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public void EnterUpgradeableReadLock();
    /// <summary>
    /// 尝试进入可升级模式锁定状态,可以选择超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入可升级模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="timeout">等待的间隔;或为 -1 毫秒,表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入可升级模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="timeout"/> 为负数,但它不等于-1 毫秒为单位),这是唯一允许的值为负。- 或 -值 <paramref name="timeout"/> 大于 <see cref="F:System.Int32.MaxValue"/> 毫秒为单位)。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterUpgradeableReadLock(TimeSpan timeout);
    /// <summary>
    /// 尝试进入可升级模式锁定状态,可以选择超时时间。
    /// </summary>
    /// 
    /// <returns>
    /// 如果调用线程已进入可升级模式,则为 true;否则为 false。
    /// </returns>
    /// <param name="millisecondsTimeout">等待的毫秒数,或为 -1 (<see cref="F:System.Threading.Timeout.Infinite"/>),表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入可升级模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="millisecondsTimeout"/> 为负数,但它不是等于 <see cref="F:System.Threading.Timeout.Infinite"/> (-1),这是唯一允许的值为负。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception>
    [__DynamicallyInvokable]
    public bool TryEnterUpgradeableReadLock(int millisecondsTimeout);
    /// <summary>
    /// 减少读取模式的递归计数,并在生成的计数为 0(零)时退出读取模式。
    /// </summary>
    /// <exception cref="T:System.Threading.SynchronizationLockException">在读取模式中,当前线程不已进入该锁。</exception>
    [__DynamicallyInvokable]
    public void ExitReadLock();
    /// <summary>
    /// 减少写入模式的递归计数,并在生成的计数为 0(零)时退出写入模式。
    /// </summary>
    /// <exception cref="T:System.Threading.SynchronizationLockException">当前线程不已进入写入模式的锁定。</exception>
    [__DynamicallyInvokable]
    public void ExitWriteLock();
    /// <summary>
    /// 减少可升级模式的递归计数,并在生成的计数为 0(零)时退出可升级模式。
    /// </summary>
    /// <exception cref="T:System.Threading.SynchronizationLockException">当前线程不已进入可升级模式的锁定。</exception>
    [__DynamicallyInvokable]
    public void ExitUpgradeableReadLock();
    /// <summary>
    /// 释放 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 类的当前实例所使用的所有资源。
    /// </summary>
    /// <exception cref="T:System.Threading.SynchronizationLockException"><see cref="P:System.Threading.ReaderWriterLockSlim.WaitingReadCount"/> 是大于零。- 或 -<see cref="P:System.Threading.ReaderWriterLockSlim.WaitingUpgradeCount"/> 是大于零。- 或 -<see cref="P:System.Threading.ReaderWriterLockSlim.WaitingWriteCount"/> 是大于零。</exception><filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public void Dispose();
    /// <summary>
    /// 获取一个值,该值指示当前线程是否已进入读取模式的锁定状态。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程已进入读取模式,则为 true;否则为 false。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public bool IsReadLockHeld { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取一个值,该值指示当前线程是否已进入可升级模式的锁定状态。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程已进入可升级模式,则为 true;否则为 false。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public bool IsUpgradeableReadLockHeld { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取一个值,该值指示当前线程是否已进入写入模式的锁定状态。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程已进入写入模式,则为 true;否则为 false。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public bool IsWriteLockHeld { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取一个值,该值指示当前 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象的递归策略。
    /// </summary>
    /// 
    /// <returns>
    /// 枚举值之一,用于指定锁定递归策略。
    /// </returns>
    [__DynamicallyInvokable]
    public LockRecursionPolicy RecursionPolicy { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取已进入读取模式锁定状态的独有线程的总数。
    /// </summary>
    /// 
    /// <returns>
    /// 已进入读取模式锁定状态的独有线程的数量。
    /// </returns>
    [__DynamicallyInvokable]
    public int CurrentReadCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取当前线程进入读取模式锁定状态的次数,用于指示递归。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程未进入读取模式,则为 0(零);如果线程已进入读取模式但却不是以递归方式进入的,则为 1;或者如果线程已经以递归方式进入锁定模式 n - 1 次,则为 n。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int RecursiveReadCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取当前线程进入可升级模式锁定状态的次数,用于指示递归。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程没有进入可升级模式,则为 0;如果线程已进入可升级模式却不是以递归方式进入的,则为 1;或者如果线程已经以递归方式进入可升级模式 n - 1 次,则为 n。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int RecursiveUpgradeCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取当前线程进入写入模式锁定状态的次数,用于指示递归。
    /// </summary>
    /// 
    /// <returns>
    /// 如果当前线程没有进入写入模式,则为 0;如果线程已进入写入模式却不是以递归方式进入的,则为 1;或者如果线程已经以递归方式进入写入模式 n - 1 次,则为 n。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int RecursiveWriteCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取等待进入读取模式锁定状态的线程总数。
    /// </summary>
    /// 
    /// <returns>
    /// 等待进入读取模式的线程总数。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int WaitingReadCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取等待进入可升级模式锁定状态的线程总数。
    /// </summary>
    /// 
    /// <returns>
    /// 等待进入可升级模式的线程总数。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int WaitingUpgradeCount { [__DynamicallyInvokable] get; }
    /// <summary>
    /// 获取等待进入写入模式锁定状态的线程总数。
    /// </summary>
    /// 
    /// <returns>
    /// 等待进入写入模式的线程总数。
    /// </returns>
    /// <filterpriority>2</filterpriority>
    [__DynamicallyInvokable]
    public int WaitingWriteCount { [__DynamicallyInvokable] get; }
  }

     以上是对Stack和线程的有关文化的浅述,现在介绍一下线程安全的Stack:

 

     /// <summary>
    /// 表示对象的后进先出线程安全集合(栈结构)
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class TStack<T> : IEnumerable<T>, ICollection
    {
        /// <summary>
        /// 内部堆栈
        /// </summary>
        private readonly Stack<T> _mStack;

        /// <summary>
        /// 锁访问堆栈(用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问。)
        /// </summary>
        private readonly ReaderWriterLockSlim _lockStack = new ReaderWriterLockSlim();

        /// <summary>
        /// 仅用于SyncRoot属性
        /// </summary>
        private readonly object _objSyncRoot = new object();

        // Variables
        /// <summary>
        /// 初始化一个新的实例 <see cref="TStack{T}"/> class.
        /// </summary>
        public TStack()
        {
            _mStack = new Stack<T>();
        }

        /// <summary>
        /// 初始化一个新的实例 <see cref="TStack{T}"/> class.
        /// </summary>
        /// <param name="col">
        /// 开始集合
        /// </param>
        public TStack(IEnumerable<T> col)
        {
            _mStack = new Stack<T>(col);
        }

        // Init
        /// <summary>
        /// 获取枚举器
        /// </summary>
        public IEnumerator<T> GetEnumerator()
        {
            Stack<T> localStack = null;

            // 初始化枚举器
            _lockStack.PerformUsingReadLock(() =>
            {
                // 创建一个m_tlist副本
                localStack = new Stack<T>(_mStack);
            });

            // 获取枚举器
            foreach (T item in localStack)
                yield return item;
        }


        /// <summary>
        /// 获取枚举器
        /// </summary>
        IEnumerator IEnumerable.GetEnumerator()
        {
            Stack<T> localStack = null;

            // 初始化枚举器
            _lockStack.PerformUsingReadLock(() =>
            {
                // 创建一个m_TList的副本
                localStack = new Stack<T>(_mStack);
            });

            // 获取枚举器
            foreach (T item in localStack)
                yield return item;
        }


        /// <summary>
        /// 复制到一个数组
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        public void CopyTo(Array array, int index)
        {
            _lockStack.PerformUsingReadLock(() => _mStack.ToArray().CopyTo(array, index));
        }

        /// <summary>
        ///堆栈中的项目数
        /// </summary>
        public int Count
        {
            get
            {
                return _lockStack.PerformUsingReadLock(() => _mStack.Count);
            }
        }

        /// <summary>
        /// 总为真
        /// </summary>
        public bool IsSynchronized
        {
            get { return true; }
        }

        /// <summary>
        ///同步根
        /// </summary>
        public object SyncRoot
        {
            get { return _objSyncRoot; }
        }


        /// <summary>
        ///清除集合
        /// </summary>
        public void Clear()
        {
            _lockStack.PerformUsingWriteLock(() => _mStack.Clear());
        }

        // Clear
        /// <summary>
        ///如果项目在堆栈中,则为true
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Contains(T item)
        {
            return _lockStack.PerformUsingReadLock(() => _mStack.Contains(item));
        }

        // 包含
        /// <summary>
        /// 返回堆栈中的顶部项,而不从堆栈中删除它
        /// </summary>
        /// <returns></returns>
        public T Peek()
        {
            return _lockStack.PerformUsingReadLock(() => _mStack.Peek());
        }

        // Peek
        /// <summary>
        ///删除并返回堆栈中的顶部项目
        /// </summary>
        /// <returns></returns>
        public T Pop()
        {
            return _lockStack.PerformUsingWriteLock(() => _mStack.Pop());
        }

        // Pop
        /// <summary>
        /// 将一个项目插入堆栈
        /// </summary>
        /// <param name="item"></param>
        public void Push(T item)
        {
            _lockStack.PerformUsingWriteLock(() => _mStack.Push(item));
        }

        // Push
        /// <summary>
        ///将堆栈转换为数组
        /// </summary>
        /// <returns></returns>
        public T[] ToArray()
        {
            return _lockStack.PerformUsingReadLock(() => _mStack.ToArray());
        }

        // ToArray
        /// <summary>
        /// 将容量设置为堆栈中实际的元素数量
        /// </summary>
        public void TrimExcess()
        {
            _lockStack.PerformUsingWriteLock(() => _mStack.TrimExcess());
        }
    }

    以上的操作方法承袭了IEnumerable<T>,
ICollection八个接口。风乐趣的,能够对IEnumerable<T>,
ICollection三个接口举办细致的询问。

 

网站地图xml地图