我有一個在時間和內存方面構建起來很昂貴的類。我想保留這些東西,並在需要時將它們分配到同一進程中的多個線程。是否有.NET的通用對象池?
是否有一個通用的對象池已經過測試和驗證? (我不想COM +池。)
我有一個在時間和內存方面構建起來很昂貴的類。我想保留這些東西,並在需要時將它們分配到同一進程中的多個線程。是否有.NET的通用對象池?
是否有一個通用的對象池已經過測試和驗證? (我不想COM +池。)
沒有Cheeso,沒有一般對象池這樣。但這是一個好主意。我認爲這將是非常簡單的發展。關鍵是讓它在一個線程環境中運行良好。
我認爲這是一個有趣的設計問題。例如,如果這需要在大規模的服務器級別的硬件 - 和 - 你會給對象indivudual線程經常那麼你可以這樣做:
這樣就避免了大多數請求的每線程爭用。
不同的操作條件會導致您不同的設計。例如,如果對象分配很少或者線程數量很少,那麼只需對集合進行鎖定可能會更簡單。這不會很好地擴展,但在這種情況下,它需要。
如果您正確設計類或接口,那麼您可以隨時改變實現來處理更復雜的場景。
爲什麼不寫一個單例,它只是作爲已經創建的對象數組的網關。
當一個對象被分發時,然後將它從可用列表中刪除,將其放入檢出列表中,然後在返回時將其反轉。
通過爲此使用一個單例,您有一個要調用的所有東西的靜態類,如果昂貴的類是單例的內部類,那麼沒有其他東西可以創建昂貴的類,並且您可以控制有多少個對象輕鬆創建。
從MSDN拉直,這裏是在.NET 4中使用新的併發收集類型之一的例子:
下面的例子演示如何實現與
System.Collections.Concurrent.ConcurrentBag<T>
作爲其後備存儲的對象池。
public class ObjectPool<T>
{
private ConcurrentBag<T> _objects;
private Func<T> _objectGenerator;
public ObjectPool(Func<T> objectGenerator)
{
if (objectGenerator == null)
throw new ArgumentNullException("objectGenerator");
_objects = new ConcurrentBag<T>();
_objectGenerator = objectGenerator;
}
public T GetObject()
{
T item;
if (_objects.TryTake(out item))
return item;
return _objectGenerator();
}
public void PutObject(T item)
{
_objects.Add(item);
}
}
謝謝你,我看到了這一個。它依賴於.NET 4.0。不幸的是,我依賴於NET 2.0。 ! – Cheeso
鏈接,也許:[如何:使用ConcurrentBag創建對象池](http://msdn.microsoft.com/en-us/library/ff458671%28v=vs.110%29.aspx) –
280Z28提出的ObjectPool類看起來不錯。您也可以考慮創建另一個實現IDisposable的類並封裝GetObject()的返回值。這將確保對象返回到您的池並讀取很好:
class ObjectPoolReference<T> : IDisposable
{
public ObjectPool<T> Pool { get; private set; }
public T Instance { get; private set; }
public ObjectPoolReference(ObjectPool<T> pool, T instance)
{
Pool = pool;
Instance = instance;
}
~ObjectPoolReference()
{
Dispose();
}
#region IDisposable Members
private bool _Disposed = false;
public void Dispose()
{
if (!_Disposed)
{
Pool.PutObject(Instance);
_Disposed = true;
}
}
#endregion
}
//instance of the pool
ObjectPool<Foo> Pool;
//"using" ensures the reference is disposed at the end of the block, releasing the object back to the pool
using (var Ref = Pool.GetObject())
{
Ref.Instance.DoSomething();
}
只是爲了分享。我使用Apache公共池作爲模型創建了一個通用的.net公共池庫。 http://cobrary.wordpress.com/net-common-pool-library/
那麼雅,這將工作。一個對象池可以非常簡單。但是接下來還有更多的細節,比如有界對象總體(不低於x,不高於y),命名對象,對象屬性等等。我只是想知道是否有人設計過它並考慮過這些事情。 – Cheeso
@Cheeso - 您可能想將其添加到您的問題中,因爲它會改變相當多的問題。 –