C#创建安全的栈创建安全的栈(Stack)存储结构存储结构
主要为大家详细介绍了C#创建安全的栈(Stack)存储结构的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
在C#中,用于存储的结构较多,如:DataTable,DataSet,List,Dictionary,Stack等结构,各种结构采用的存储的方式存在差异,效率也必然各有优缺点。现在介绍一种后进先出的数据结构。
谈到存储结构,我们在项目中使用的较多。对于Task存储结构,栈与队列是类似的结构,在使用的时候采用不同的方法。C#中栈(Stack)是编译期间就分配好的内存空间,因此你的代码中必须就栈
的大小有明确的定义;堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。
在C#中,栈通常保存着我们代码执行的步骤。C#中的引用类型存储在栈中,在程序运行的时候,每个线程(Thread)都会维护一个自己的专属线程堆栈。当一个方法被调用的时候,主线程开始在所属程
序集的元数据中,查找被调用方法,然后通过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);