2012-02-23 39 views
12

Tôi có hai ứng dụng .net chạy trên cùng một máy. Ứng dụng đầu tiên là 'Engine'. Nó xây dựng hình ảnh - kích thước của hình ảnh là khoảng 4M. Ứng dụng thứ hai là 'Trình xem'. Nó cho thấy những hình ảnh mà 'Engine' gửi đi. Động cơ gửi hình ảnh sau mỗi 10-15 giây.Truyền dữ liệu lớn giữa các ứng dụng .net trên cùng một máy tính

Câu hỏi của tôi là cách bast truyền hình ảnh từ động cơ đến người xem là gì. Hiện tại, tôi đang sử dụng FileSystem cho việc này. Engine ghi hình ảnh vào thư mục hệ thống tệp và người xem nhận tệp này bằng FileSystemWatcher.

Phương pháp đó có ổn không? Điều đó có đáng tin cậy không?

+0

Là người nổi tiếng ở đây ... các bài kiểm tra đơn vị của riêng bạn nên chứng minh xem nó có ổn cả và đáng tin cậy không. –

+0

@AdamHouldsworth Tôi không nhận thấy OP nói rằng họ thậm chí còn sử dụng các bài kiểm tra đơn vị. Có nghĩa là tuyên bố đó là _also_ hơi không liên quan. –

+0

@ Mr.Disappointment Không thực sự. Các bài kiểm tra đơn vị sẽ hướng tới việc chứng minh độ tin cậy và thành công chức năng của phương pháp tiếp cận - các nền tảng của câu hỏi. Ngoài ra, điểm pedantic là nếu họ không sử dụng các bài kiểm tra đơn vị để chứng minh công cụ này, họ nên. –

Trả lời

5

Có nhiều lựa chọn tốt:

  • Message Queue
  • Các Ống có tên (trực tiếp)
  • Các tệp được ánh xạ bộ nhớ
  • WCF on Named Ống hoặc MSMQ

Bất kỳ loại nào trong số đó đều đủ nhanh để tôi đề xuất dễ triển khai nhất.

Hàng đợi tin nhắn (MSMQ) theo ý kiến ​​của bạn là đơn giản nhất để sử dụng, cho phép bạn chuyển đối tượng (trái ngược với luồng) và cung cấp cho bạn lưu lượng truy cập tùy chọn (hữu ích trong trường hợp người gửi hoặc người nhận không hoạt động). Tất cả điều này là đúng cho WCF trên MSMQ nhưng WCF có nghĩa là chi phí cao hơn, phức tạp và cấu hình liên quan và không có thêm (trong trường hợp này) giá trị.

Gởi như thế này:

MessageQueue queue = new MessageQueue(".\\private$\\ImagesQueue"); 
Message msg = new Message 
{ 
    Formatter = new BinaryMessageFormatter(), 
    Body = myImage, 
    Label = "Image" 
}; 
queue.Send(msg); 

Nhận:

MessageQueue queue = new MessageQueue(".\\private$\\ImagesQueue"); 
msg = queue.Receive(TimeSpan.FromMilliseconds(100)); 
if (msg != null) 
{ 
    msg.Formatter = new BinaryMessageFormatter(); 
    myImage = (MyImage)msg.Body; 
} 

Queue cần phải được tạo trước khi sử dụng. Bạn có thể làm điều đó khi ứng dụng của bạn bắt đầu

Có này trong lớp học của bạn:

private const string queueName = ".\\private$\\ImagesQueue"; 

Và trong ứng dụng khởi tạo/khởi động chắc chắn rằng bạn có hàng đợi của bạn:

if (!MessageQueue.Exists(queueName) 
{ 
    MessageQueue myQueue = MessageQueue.Create(queueName); 
} 

Với cơ chế hàng đợi này, Động cơ không phải đợi cho Trình xem hoàn tất. Điều này sẽ cải thiện hiệu suất nhận thức bởi vì bạn có thể tạo ra hình ảnh tiếp theo (thực sự là số lượng của chúng) trong khi hình ảnh trước đó vẫn đang được xem. Không dễ dàng để đạt được với các tập tin ánh xạ bộ nhớ.

MSMQ là thành phần Windows chuẩn nhưng cần phải được bật trong Tính năng của Windows.

+0

Cảm ơn bạn. Tôi thích Message Queue aproach vì những gì bạn viết: "Message Queue (MSMQ) theo ý kiến ​​của tôi là đơn giản nhất để sử dụng, cho phép bạn chuyển đối tượng (trái ngược với luồng) và cung cấp cho bạn khả năng lưu thông tùy chọn (hữu ích trong trường hợp người gửi hoặc người nhận không hoạt động)). " Cảm ơn. – MTs

+0

Rất vui được giúp đỡ. Tôi đã mở rộng câu trả lời của mình với nhiều chi tiết hơn về cách tạo hàng đợi trong khởi động ứng dụng. –

11

Vì .NET Framework 4.0 bạn có thể sử dụng tệp ánh xạ bộ nhớ cho điều này, tôi tin rằng nó sẽ nhanh hơn phương pháp dựa trên hệ thống tệp vì bạn không cần các hoạt động IO hệ thống tệp tốn kém.

Tệp bộ nhớ ánh xạ chứa nội dung của tệp trong bộ nhớ ảo . Ánh xạ giữa một tệp và không gian bộ nhớ cho phép ứng dụng , bao gồm nhiều quá trình, để sửa đổi tệp theo số đọc và ghi trực tiếp vào bộ nhớ. Các tệp có ánh xạ bộ nhớ có thể được chia sẻ trên nhiều quy trình. Quy trình có thể ánh xạ tới cùng một tệp ánh xạ bộ nhớ bằng cách sử dụng tên chung được chỉ định bởi quá trình đã tạo tệp

Vì vậy, để chia sẻ MMF trên nhiều quy trình bạn chỉ cần chia sẻ một tên MMF, do đó bạn có thể xem xét phương pháp sau đây:

  • Engine sẽ tạo tập tin MMF và chia sẻ với Viewer chỉ là một tên (string)
  • Quang cảnh tiếp cận MMF sử dụng MemoryMappedFile.OpenExisting(sharedName) phương pháp (xem MSDN cho một ví dụ truy cập cùng MMF từ các quá trình khác nhau)

Liên kết hữu ích:

  • Memory-Mapped Files
  • Working with memory mapped files in .NET 4 - khuyên bạn nên đọc bài viết này trong đó mô tả tại sao MMF thực sự "is the most efficient way for multiple processes on a single machine to communicate with each other". Về cơ bản nó cho thấy rằng tất cả các tùy chọn IPC khác dựa trên MMF.

(Từ nêu trên bài viết) Nếu chúng tôi kiểm tra phương pháp IPC khác chúng ta có thể thấy kiến ​​trúc sau: enter image description here

0

Vâng, đó là một cách tiếp cận hợp lệ. Và giả sử mã của bạn không chứa lỗi, có nó đáng tin cậy.

Nhưng chậm. Nếu thông lượng là một mối quan ngại, bạn có thể cần phải sử dụng Ổ cắm (nếu bạn muốn chia động cơ và trình xem cho các máy khác nhau) hoặc các đường ống được đặt tên (cho các liên lạc giữa các quá trình trên cùng một máy).

0

Sử dụng ZeroMQ. Nó rất dễ sử dụng (dễ dàng hơn WCF nếu bạn chỉ gửi một loại tin nhắn), không có nhiều chi phí, và nói chung là một giải pháp tốt cho nhiều vấn đề truyền thông liên tiến trình.

+0

Tôi không nghĩ ZMQ là một lựa chọn tuyệt vời trong trường hợp này - ZMQ là tuyệt vời khi bạn có nhiều tin nhắn nhỏ được gửi - và thứ tự chúng nhận được không cần phải được đảm bảo (hoặc thậm chí là chúng đến) . Hữu ích cho một cái gì đó giống như một cổ phiếu ticker được cập nhật 60 lần một giây. Trong trường hợp này, mặc dù chúng tôi có một thông điệp rất lớn được gửi mỗi 10-15 giây - ZMQ không lý tưởng cho trường hợp sử dụng này. – MattDavey

+0

Có, nhưng bạn đang gửi tin nhắn giữa hai thành phần trên cùng một máy. Bạn sẽ không gặp bất kỳ mất mát dữ liệu nào liên quan đến UDP. – zmbq

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