2009-11-04 24 views
16

Tôi có một lớp học đắt tiền để xây dựng, về mặt thời gian và trí nhớ. Tôi muốn duy trì một hồ bơi của những điều này và phân phối chúng ra theo yêu cầu cho nhiều chủ đề trong cùng một quá trình.Có một nhóm đối tượng chung cho .NET không?

Có hồ bơi đối tượng có mục đích chung đã được thử nghiệm và chứng minh không? (Tôi không muốn kết hợp COM +.)

Trả lời

5

Không Cheeso, không có hồ bơi đối tượng chung như thế này. Nhưng đó là một ý kiến ​​hay. Tôi nghĩ điều này sẽ khá đơn giản để phát triển. Điều quan trọng là làm cho nó hoạt động tốt trong môi trường luồng.

Tôi nghĩ đây là một vấn đề thiết kế thú vị. Ví dụ, nếu điều này cần phải mở rộng quy mô trên phần cứng lớp sever -and- bạn sẽ cung cấp cho các đối tượng để đề indivudual thường thì bạn có thể làm điều này:

  1. Giữ một hồ bơi trung tâm duy nhất của đối tượng.
  2. Giữ một hồ bơi theo chủ đề (bộ nhớ cache) được điền khi được gọi lần đầu tiên cho một chuỗi và khi nó trở nên trống.

Bằng cách này, bạn tránh tranh chấp theo chủ đề cho hầu hết các yêu cầu.

Các điều kiện vận hành khác nhau sẽ đưa bạn đến một thiết kế khác. Ví dụ, nếu phân bổ đối tượng là hiếm hoặc số lượng chủ đề là thấp, sau đó nó có thể đơn giản chỉ để có một khóa xung quanh một bộ sưu tập. Điều này sẽ không quy mô tốt, nhưng trong trường hợp này, nó sẽ cần phải.

Nếu bạn thiết kế chính xác lớp hoặc giao diện, bạn có thể thay đổi triển khai theo thời gian để xử lý các tình huống phức tạp hơn.

1

Tại sao không chỉ viết một singleton chỉ đóng vai trò là cổng vào mảng đối tượng đã được tạo.

Khi một đối tượng được đưa ra, sau đó loại bỏ nó khỏi danh sách có sẵn, đặt nó trong danh sách đã kiểm tra, và sau đó khi nó được trả về, đảo ngược điều đó.

Bằng cách sử dụng một singleton cho điều này bạn có một lớp tĩnh cho tất cả mọi thứ để gọi, và nếu lớp đắt tiền là một lớp bên trong của singleton, sau đó không có gì khác có thể tạo ra các lớp đắt tiền, và bạn có thể kiểm soát bao nhiêu đối tượng tạo ra, dễ dàng.

+0

Vâng ya, điều đó sẽ hiệu quả. một nhóm đối tượng có thể khá đơn giản.Nhưng sau đó có thêm niceties như, một đối tượng bị giới hạn (không thấp hơn x, không cao hơn y), các đối tượng được đặt tên, các thuộc tính đối tượng, điều đó. Tôi chỉ tự hỏi liệu có ai đó đã thiết kế nó và xem xét những thứ này không. – Cheeso

+0

@Cheeso - bạn có thể muốn thêm điều đó vào câu hỏi của bạn, vì nó sẽ thay đổi câu hỏi một chút. –

21

kéo thẳng từ MSDN, đây là một ví dụ của việc sử dụng một trong những loại bộ sưu tập đồng thời mới trong .NET 4:

Ví dụ sau đây cho thấy làm thế nào để thực hiện một hồ bơi đối tượng với một System.Collections.Concurrent.ConcurrentBag<T> như cửa hàng ủng hộ mình.

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); 
    } 
} 
+1

Cảm ơn bạn, tôi đã thấy cái này. Nó phụ thuộc vào .NET 4.0. Thật không may, tôi phụ thuộc vào NET 2.0. !!! – Cheeso

+1

Liên kết, có thể: [Cách tạo: Tạo một đối tượng Pool bằng cách sử dụng ConcurrentBag] (http://msdn.microsoft.com/en-us/library/ff458671%28v=vs.110%29.aspx) –

6

Lớp ObjectPool được đề xuất bởi 280Z28 trông khá tốt. Bạn cũng có thể xem xét việc tạo một lớp khác thực hiện IDisposable và kết thúc giá trị trả về của GetObject(). Điều này sẽ đảm bảo các đối tượng được trả về hồ bơi của bạn và đọc độc đáo:

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(); 
} 
Các vấn đề liên quan