2012-04-11 22 views
7

Tôi cần truy vấn FIFO đơn người sản xuất, đơn người tiêu dùng vìcó tốt không khi sử dụng BlockingCollection <T> làm truy vấn FIFO đơn, sản xuất đơn lẻ?

  • Tôi cần xử lý thư theo thứ tự nhận được.
  • Tôi cần làm điều này không đồng bộ vì người gọi không nên đợi trong khi tôi đang xử lý tin nhắn.
  • Xử lý tin nhắn tiếp theo sẽ chỉ được bắt đầu khi quá trình xử lý tin nhắn trước đó kết thúc. Đôi khi tần suất thông báo "nhận" cao hơn tần suất của thông báo "đang xử lý". Nhưng trung bình tôi sẽ có thể xử lý tất cả các tin nhắn, chỉ đôi khi tôi phải "xếp hàng" gói chúng.

Vì vậy, nó khá giống TCP/IP tôi nghĩ, nơi bạn có một nhà sản xuất và một người tiêu dùng, SOMETIMES bạn có thể nhận tin nhắn nhanh hơn bạn có thể xử lý, vì vậy bạn phải truy vấn chúng. Trường hợp thứ tự IS quan trọng và nơi người gọi hoàn toàn không quan tâm đến những gì bạn đang làm với nội dung đó.

này nghe có vẻ khá dễ dàng và tôi có khả năng có thể sử dụng chung Queue cho rằng, nhưng tôi muốn sử dụng BlockingCollection cho rằng bởi vì tôi không muốn viết bất kỳ mã với ManualResetEvent, vv

Làm thế nào phù hợp BlockingCollection cho nhiệm vụ của tôi và có lẽ bạn có thể gợi ý cái gì khác?

Trả lời

11

BlockingCollection thực hiện lớp học IProducerConsumerCollection giao diện để hoàn toàn phù hợp với yêu cầu của bạn.

Bạn có thể tạo hai Công việc, một cho nhà sản xuất không đồng bộ và một công ty khác làm công nhân tiêu dùng. Trước đây sẽ thêm các mục vào BlockingCollection và sau đó chỉ tiêu thụ ngay sau khi mới có sẵn trong thứ tự FIFO.

ứng dụng sản xuất-tiêu dùng mẫu sử dụng TPL TasksBlockingCollection:

class ProducerConsumer 
{ 
    private static BlockingCollection<string> queue = new BlockingCollection<string>(); 

    static void Main(string[] args) 
    { 
     Start(); 
    } 

    public static void Start() 
    { 
     var producerWorker = Task.Factory.StartNew(() => RunProducer()); 
     var consumerWorker = Task.Factory.StartNew(() => RunConsumer()); 

     Task.WaitAll(producerWorker, consumerWorker); 
    } 

    private static void RunProducer() 
    { 
     int itemsCount = 100; 

     while (itemsCount-- > 0) 
     { 
      queue.Add(itemsCount + " - " + Guid.NewGuid().ToString()); 
      Thread.Sleep(250); 
     } 
    } 

    private static void RunConsumer() 
    { 
     foreach (var item in queue.GetConsumingEnumerable()) 
     { 
      Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.ffff") + " | " + item); 
     } 
    } 
} 

IProducerConsumerCollection:

Định nghĩa phương pháp để thao tác bộ sưu tập thread-safe dành cho sản xuất/sử dụng của người tiêu dùng. Giao diện này cung cấp một đại diện hợp nhất cho các bộ sưu tập của người sản xuất/người tiêu dùng để các mức trừu tượng cao hơn trừu tượng như System.Collections.Concurrent.BlockingCollection (Of T) có thể sử dụng bộ sưu tập làm cơ chế lưu trữ cơ bản.

+0

Tôi hy vọng rằng việc thực thi FIFO mặc định của 'BlockingCollection' sẽ không bị thay đổi trong một số phiên bản tiếp theo , nhưng đây là một câu hỏi khác ... – javapowered

+0

Tôi tin rằng bạn nên được miễn là bạn đang tham chiếu đến giao diện 'IProducerConsumerCollection', và thực hiện các lớp BCL có thể; t thay đổi theo cách chính như FIFO để một cái gì đó khác – sll

+2

Tôi thấy phương thức Start() chờ hai nhiệm vụ để hoàn thành. Rõ ràng nhiệm vụ 'producerWorker' sẽ kết thúc, nhưng' consumerWorker' sẽ không bao giờ kết thúc. Điều đó có nên được tính đến không? –

0

Vì đó là hàng đợi bạn cần, tại sao không dính vào hàng đợi? Bạn có thể sử dụng Syncrhonized Queue.

+0

Không chặn. –

+0

Martin phải, [MSDN] (http://msdn.microsoft.com/en-us/library/system.collections.queue.synchronized.aspx): 'Liệt kê thông qua một bộ sưu tập thực chất không phải là một thủ tục an toàn thread. Ngay cả khi một bộ sưu tập được đồng bộ, các chủ đề khác vẫn có thể sửa đổi bộ sưu tập, khiến cho điều tra viên đưa ra một ngoại lệ. Để đảm bảo an toàn luồng trong quá trình liệt kê, bạn có thể khóa bộ sưu tập trong toàn bộ liệt kê hoặc nắm bắt các ngoại lệ do các thay đổi được thực hiện bởi các chủ đề khác ' – sll

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