大抵而言,Singleton 模式應該是設計模式中相當常用的一種了。它能夠節(jié)省寶貴的 CPU 或內(nèi)存資源,避免不必要的創(chuàng)建對象開銷。然而,在多線程應用中,對于那些非線程安全的數(shù)據(jù)庫組件,傳統(tǒng)的 Singleton 將容易造成不穩(wěn)定。如果使用 Synclock 進行同步,性能損耗可能將更大,特別在并發(fā)訪問高的 ASP.NET 應用中。
前十幾天和網(wǎng)友聊天的時候,他把 ThreadwiseSingleton 發(fā)給了我,我隨后改寫成泛型類。事實上,它基于 Threadslot 構(gòu)建,因此達到了線程隔離的效果。您需要傳入一個 Func(Of TResult) 完成初始化的工作。如果您的類中含有非托管資源,并無法預見可能的錯誤時,請使用一個 Try...Finally... 包裹將要運行的程序。同時感到抱歉的是,拖延了很久很久才發(fā)出來。
Imports System.Threading
''' <summary> ''' 一個線程隔離的 Singleton。 ''' </summary> Public Class ThreadwiseSingletonClass ThreadwiseSingleton(Of T As IDisposable) Private Shared _Factory As Func(Of T)
''' <summary> ''' 獲取構(gòu)建此實例的工廠類。 ''' </summary> Public Shared Property Factory()Property Factory() As Func(Of T) Get Return _Factory End Get Set(ByVal value As Func(Of T)) _Factory = value End Set End Property ''' <summary> ''' 獲得線程中的唯一實例。 ''' </summary> Public Shared ReadOnly Property Instance()Property Instance() As T Get Dim threadSlot As LocalDataStoreSlot = Thread.GetNamedDataSlot(GetType(T).ToString) Dim threadSlotObj As Object = Thread.GetData(threadSlot)
If threadSlotObj Is Nothing Then 'Create singleton instance Dim ins As T = Factory.Invoke Thread.SetData(threadSlot, ins) Return ins Else Return DirectCast(threadSlotObj, T) End If End Get End Property
''' <summary> ''' 私有的構(gòu)造函數(shù)。 ''' </summary> Private Sub New()Sub New()
End Sub ''' <summary> ''' 釋放此 Singleton 實例使用的資源。請不要直接調(diào)用 Instance.Dispose()。 ''' </summary> Public Shared Sub Dispose()Sub Dispose() Instance.Dispose() '放空槽 Dim threadSlot As LocalDataStoreSlot = Thread.GetNamedDataSlot(GetType(T).ToString) Thread.SetData(threadSlot, Nothing) End Sub End Class
|