2010-02-27 31 views
6

Tôi đã đọc "Chuyên gia C# 2008 đối tượng kinh doanh" của Rockford Lhotka, nơi có một thứ như cổng dữ liệu tóm tắt độc đáo nơi dữ liệu đến từ đó. Khi sử dụng DataPortal.Update (điều này), như bạn có thể đoán vẫn còn 'this' đối với cơ sở dữ liệu, một đối tượng được trả về - 'this this' tồn tại với bất kỳ thay đổi nào mà db tạo ra, ví dụ. dấu thời gian.C#: Có cách nào để dễ dàng tìm/cập nhật tất cả các tham chiếu đến một đối tượng không?

Lhotka đã viết thường xuyên và rất tình cờ, mà bạn phải đảm bảo cập nhật tất cả các tham chiếu đến các đối tượng cũ sang đối tượng quay trở lại mới. Làm cho tinh thần, nhưng là có một cách dễ dàng để tìm tất cả các tài liệu tham khảo cho các đối tượng cũ và thay đổi chúng? Rõ ràng GC theo dõi tài liệu tham khảo, là nó có thể gõ vào đó?

Chúc mừng

Trả lời

4

GC không thực sự theo dõi các tham chiếu đến đối tượng. Thay vào đó, nó tính toán các đối tượng nào có thể truy cập được bắt đầu từ các đối tượng toàn cầu và ngăn xếp tại thời gian chạy và thực hiện một số biến thể của thuật toán "lấp đầy lũ".

Cụ thể cho vấn đề của bạn, tại sao không chỉ có một proxy giữ tham chiếu đến đối tượng "thực"? Bằng cách này, bạn chỉ cần cập nhật tại một địa điểm.

+0

Có, bạn có thể sử dụng một mẫu tương tự như của một Flyweight. http://en.wikipedia.org/wiki/Flyweight_pattern – Josh

+1

+1. Như Vlad đã chỉ ra, một cách dễ dàng là để giới thiệu thêm một mức độ bất định. (@Josh: Bạn có chắc rằng * Flyweight * là thuật ngữ thích hợp ở đây không?) –

+0

@andras, trong ví dụ GoF sử dụng glyphs của trình soạn thảo văn bản làm ví dụ có vẻ lạ. Nhưng nếu Vlad nghĩa là có một đối tượng dữ liệu "nặng" chứa dữ liệu và một loạt các đối tượng "liên kết" khác tham chiếu đến điều này, vâng tôi nghĩ rằng nó sẽ rất giống với ý định của một con ruồi. Mặc dù tiết kiệm không gian không phải là động lực chính ở đây. – Josh

5

profiling API's để làm điều này nhưng không có gì để sử dụng chung. Một giải pháp có thể và một giải pháp mà tôi đã sử dụng là thực hiện trong cơ sở một cơ chế theo dõi, trong đó mỗi cá thể của đối tượng thêm một WeakReference vào một tập hợp tĩnh.

tôi đã có điều kiện này được biên soạn cho DEBUG xây dựng nhưng nó có lẽ sẽ không phải là một ý tưởng tốt để dựa vào điều này trong một thông cáo xây dựng.

// simplified example 
// do not use. performance would suck 
abstract class MyCommonBaseClass { 

    static readonly List<WeakReference> instances = new List<WeakReference>(); 

    protected MyCommonBaseClass() { 
     lock (instances) { 
      RemoveDeadOnes(); 
      instances.Add(new WeakReference(this)); 
     } 
    } 

} 
+0

+1: Kỹ thuật tuyệt vời cho trường hợp khi bạn điều khiển đối tượng. – Vlad

+0

Wow ý tưởng tuyệt vời, cảm ơn bạn. – jptsetung

0

Không có cách nào đơn giản để thực hiện việc này trực tiếp, tuy nhiên, Son of Strike có khả năng này. Nó cho phép bạn đi sâu vào tất cả các tham chiếu đối tượng được CLR theo dõi và xem đối tượng nào đang tham chiếu đến bất kỳ đối tượng cụ thể nào, v.v.

Đây là một số tutorial for learning CLR debugging via SoS tốt.

0

Nếu bạn đang đi qua tham chiếu đối tượng xung quanh và những tài liệu tham khảo đối tượng vẫn không thay đổi, sau đó bất kỳ thay đổi thực hiện cho các đối tượng trong một lớp kiên trì sẽ ngay lập tức hiển thị cho mọi người tiêu dùng khác của đối tượng. Tuy nhiên, nếu đối tượng của bạn vượt qua ranh giới dịch vụ thì các hội đồng ở mỗi bên của đối tượng sẽ xem các đối tượng khác nhau chỉ là bản sao carbon. Ngoài ra nếu bạn đã tạo bản sao của đối tượng hoặc đã tạo các loại vô danh kết hợp các thuộc tính từ đối tượng ban đầu, thì những thứ đó sẽ khó theo dõi - và dĩ nhiên với GC, đây là các đối tượng mới không có liên kết với đối tượng gốc.

Nếu bạn có một số loại khóa hoặc ID trong đối tượng thì việc này trở nên dễ dàng hơn. Chìa khóa không phải là một ID cơ sở dữ liệu, nó có thể là một GUID được tạo mới khi đối tượng được khởi tạo, và không được thay đổi cho toàn bộ vòng đời của đối tượng (nghĩa là nó là một thuộc tính có một getter nhưng không có setter) - vì nó là một thuộc tính nó sẽ tồn tại trên các ranh giới dịch vụ, do đó đối tượng của bạn sẽ vẫn có thể nhận dạng được. Sau đó, bạn có thể sử dụng LINQ hoặc thậm chí các vòng lặp cũ (icky!) Để lặp qua bất kỳ bộ sưu tập nào có khả năng chứa một bản sao của đối tượng được cập nhật và nếu tìm thấy nó, bạn có thể hợp nhất các thay đổi đó lại.

Có nói điều này, tôi sẽ không nghĩ rằng bạn có quá nhiều bản sao trôi nổi xung quanh. NẾU bạn làm thì những nơi mà các bản sao này nên được bản địa hóa rất nhiều. Đảm bảo rằng đối tượng của bạn thực hiện INotifyPropertyChanged cũng sẽ giúp tuyên truyền các thay đổi nếu bạn giữ một danh sách ở một vị trí mà sau đó bị ràng buộc trực tiếp hoặc gián tiếp ở một số điểm khác.

Các vấn đề liên quan