C#創立平安的棧(Stack)存儲構造。本站提示廣大學習愛好者:(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); /// <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兩個接口停止細致的理解。
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支持。