2008-11-11 16 views
6

Chúng tôi cần phát triển một số loại quản lý bộ đệm cho một ứng dụng mà chúng tôi đang phát triển bằng cách sử dụng C#.Quản lý vùng đệm bằng cách sử dụng C#

Về cơ bản, ứng dụng nhận được tin nhắn từ thiết bị khi họ đến (có thể có nhiều người trong một khoảng thời gian ngắn). Chúng ta cần xếp hàng chúng trong một số vùng đệm để chúng ta có thể xử lý chúng theo kiểu được quản lý.

Chúng tôi đã nghĩ đến việc phân bổ khối bộ nhớ trong khối 256 byte (tất cả thư nhỏ hơn) và sau đó sử dụng quản lý vùng đệm để có vùng đệm có sẵn có thể được sử dụng cho thư đến và nhóm bộ đệm sẵn sàng để được xử lý.

Vì vậy, luồng sẽ là "Lấy bộ đệm" (xử lý nó) "Bộ đệm phát hành" hoặc "Rời khỏi bộ đệm". Chúng ta cũng cần phải biết khi nào bộ đệm được lấp đầy.

Có khả năng, chúng tôi cũng sẽ cần một cách để "liếc" vào bộ đệm để xem bộ đệm ưu tiên cao nhất trong nhóm là thay vì luôn luôn nhận bộ đệm tiếp theo.

Đã có hỗ trợ cho điều này trong .NET hay có một số mã nguồn mở mà chúng tôi có thể sử dụng không?

Trả lời

4

Quản lý bộ nhớ C# sharps thực sự khá tốt, vì vậy thay vì có một vùng đệm, bạn chỉ có thể phân bổ chính xác những gì bạn cần và gắn nó vào hàng đợi. Một khi bạn đang thực hiện với bộ đệm chỉ để cho các nhà sưu tập rác xử lý nó.

Một tùy chọn khác (chỉ biết rất ít về ứng dụng của bạn), là xử lý các thông điệp tối thiểu khi bạn nhận được chúng và biến chúng thành các đối tượng chính thức (với các ưu tiên và tất cả), sau đó hàng đợi của bạn có thể ưu tiên chúng điều tra tập hợp các thuộc tính hoặc phương pháp chính xác.

Nếu thư của bạn đến quá nhanh ngay cả khi xử lý tối thiểu, bạn có thể có hai hệ thống xếp hàng. Một chỉ là một hàng đợi các bộ đệm chưa được xử lý và hàng đợi tiếp theo là hàng đợi các đối tượng tin nhắn được xây dựng từ bộ đệm.

Tôi hy vọng điều này sẽ hữu ích.

+0

không phải là một ý tưởng hay. bất cứ điều gì mà làm bất cứ điều gì để làm với interop sẽ gây ra phân mảnh (và kết quả trong bộ nhớ ngoại lệ) do GC phải ghim các đối tượng. –

+2

Interop giữa những gì? Chủ đề? Các ứng dụng? Quy trình? – grieve

+0

Tôi nghĩ nzpcmad đang hoạt động được quản lý thuần túy với P/Invoke. – user7116

2

Tại sao bạn không nhận tin nhắn, tạo đối tượng DeviceMessage (vì thiếu tên tốt hơn) và đưa đối tượng đó vào Hàng đợi? Nếu mức độ ưu tiên là quan trọng, hãy triển khai lớp PriorityQueue xử lý tự động (bằng cách đặt các đối tượng DeviceMessage theo thứ tự ưu tiên khi chúng được chèn vào hàng đợi). Có vẻ như một cách tiếp cận OO hơn, và sẽ đơn giản hóa việc bảo trì theo thời gian liên quan đến việc ưu tiên.

1

Tôi đang làm một việc tương tự. Tôi có tin nhắn đến trong các chủ đề MTA cần được phục vụ trên các chủ đề STA.

Tôi đã sử dụng BlockingCollection (một phần của phần mở rộng fx song song) được theo dõi bởi một số chuỗi STA (có thể định cấu hình, nhưng mặc định là xr * số lõi). Mỗi chủ đề cố gắng để bật một tin nhắn ra khỏi hàng đợi. Họ hoặc là thời gian ra và thử lại hoặc thành công bật một tin nhắn ra và phục vụ nó.

Tôi đã kết nối với bộ đếm nước để theo dõi thời gian rảnh, thời lượng công việc, tin nhắn đến, v.v., có thể được sử dụng để tinh chỉnh cài đặt của hàng đợi.

Bạn sẽ phải triển khai bộ sưu tập tùy chỉnh hoặc có thể mở rộng BC, để triển khai các ưu tiên mục hàng.

Một trong những lý do tại sao tôi thực hiện theo cách này là, vì tôi hiểu nó, queueing theory thường ủng hộ một dòng, nhiều máy chủ (tại sao tôi cảm thấy như tôi sẽ bắt gặp crap về điều đó?).

2

@grieve: Mạng là nguồn gốc, có nghĩa là khi bộ đệm được sử dụng dữ liệu nhận/gửi trên mạng, chúng được ghim vào bộ nhớ. xem bình luận của tôi dưới đây để xây dựng.

+0

-1, tôi khá chắc chắn rằng không gian tên System.Net tóm tắt mà tất cả các bạn tránh xa người dùng cuối sẽ không cho bạn xử lý bất kỳ điều gì trong số đó. Tôi cũng không thấy bất kỳ đề cập nào trong OP rằng ứng dụng sử dụng interop dưới mọi hình thức. – user7116

+1

Có lẽ tôi không rõ ràng - mạng luôn xảy ra trong bối cảnh không quản lý, có nghĩa là các bộ đệm bạn gửi tới API mạng (ở cuối WINSOCK riêng cho dù bạn có thích hay không ..) được ghim trong bộ nhớ và không thể được thu thập rác, cũng không được nén (di chuyển trong bộ nhớ) khi GC cố gắng nén đống. do đó, nó gây ra sự phân mảnh bộ nhớ rất lớn và các hình phạt hiệu suất như các bộ đệm có thể tồn tại đến thế hệ 1 (thậm chí có thể là gen 2) và sẽ là một cơn đau với GC, trong khi bạn tiếp tục phân bổ nhiều bộ đệm hơn –

+0

Cách chính xác để đi về nó là tạo ra một nhóm bộ đệm bạn muốn sử dụng với mạng, và do đó bộ nhớ bị mất nhưng bị ngưng tụ ở một nơi và sẽ không lấy chi phí GC để quản lý và bạn sẽ không phân bổ lại bộ đệm cho không gian bộ nhớ mà bạn đã thanh toán. Ví dụ, trong ví dụ web-server, bạn sẽ khôn ngoan để có một Cache cho các tập tin bạn đang phục vụ, giữ các bộ đệm tập tin trong bộ nhớ, và sử dụng các bộ đệm này khi sử dụng Socket.Send. - không có phân bổ hoặc hình phạt, các bộ đệm này sẽ có giá trị trong một thời gian dài trong hầu hết các tình huống thực tế. –

2

Tôi biết đây là một bài đăng cũ, nhưng tôi nghĩ bạn nên xem xét nhóm bộ nhớ được triển khai trong dự án ILNumerics. Tôi nghĩ rằng họ đã làm chính xác những gì bạn cần và nó là một đoạn mã rất hay. Tải xuống mã tại http://ilnumerics.net/ và xem tệp ILMemoryPool.cs

+0

liên kết trực tiếp tới ILMemoryPool https://ilnumericsnet.svn.sourceforge.net/svnroot/ilnumericsnet/ILNumerics/Misc/ILMemoryPool.cs – Avram