2012-01-10 38 views
6

Tôi có một ứng dụng một quy trình, hai luồng. Chủ đề 1 sẽ lắng nghe nguồn cấp dữ liệu thị trường và cập nhật báo giá mới nhất về hàng nghìn cổ phiếu. Chủ đề 2 sẽ chạy bộ đếm thời gian ở tần số lấy mẫu và chụp nhanh các trích dẫn gần đây nhất để xử lý. Hiệu quả, tôi cần phải xuống mẫu một nguồn cấp dữ liệu thị trường cực nhanh.Cách nhanh, bộ nhớ hiệu quả để truyền dữ liệu giữa các luồng trong C# là gì?

Dự đoán đầu tiên của tôi về giải pháp là sử dụng BlockingQueue. Để thực hiện điều này, tôi cần phải di chuyển chức năng hẹn giờ vào Chủ đề 1, mà tôi có thể thực hiện bằng cách kiểm tra đồng hồ mỗi lần cập nhật báo giá đến và gửi ảnh chụp nhanh các dấu ngoặc kép lên hàng đợi tại Tần số Lấy mẫu. Mối quan tâm của tôi ở đây là hàng đợi sẽ tiêu tốn rất nhiều bộ nhớ và bộ sưu tập rác sẽ làm chậm mọi thứ.

Dự đoán thứ hai của tôi là để Thread 1 sao chép dữ liệu vào một thành viên bị khóa ở tần số lấy mẫu, mà Thread 2 có thể truy cập. Mối quan tâm của tôi ở đây là các ổ khóa sẽ bị chậm.

Thirt của tôi đoán nó làm cho các nguyên tố trích dẫn dễ bay hơi. Vì một luồng chỉ viết và một luồng chỉ đọc, có lẽ điều này là thích hợp?

Có cách nào tốt nhất để truyền đạt dữ liệu giữa các chuỗi cho ứng dụng nhạy cảm độ trễ này không? Đây không phải là một ứng dụng tần số cực cao. Tôi có thể chịu đựng được độ trễ theo thứ tự của hàng chục ms.

Trả lời

7

Nếu bạn chỉ có 2 đề truy cập khu vực này (tức là đồng thời nội dung đã không bắt buộc), sau đó đơn giản nhất (và một trong những nhanh nhất) sẽ chỉ được sử dụng lock keyword:

public class QuoteStore 
{ 
    private readonly List<Quote> _quotes = new List<Quote>(); 
    private readonly object _mutex = new object(); 

    public ReadOnlyCollection<Quote> GetQuotes() 
    { 
     lock (_mutex) 
     { 
     return _quotes.ToReadOnly(); 
     } 
    } 

    public void AddQuote() 
    { 
     lock (_mutex) 
     { 
     _quotes.Add(quote); 
     } 
    } 
} 

Nếu tuy nhiên đồng thời đọc được yêu cầu này sẽ là một phù hợp cho the ReaderWriterLockSlim class. Bạn có thể có được các khóa đọc khi sao chép dữ liệu và khóa ghi khi ghi dữ liệu ví dụ:

public class QuoteStore : IDisposable 
{ 
    private readonly ReaderWriterLockSlim _mutex = new ReaderWriterLockSlim(); 
    private readonly List<Quote> _quotes = new List<Quote>(); 

    public ReadOnlyCollection<Quote> GetQuotes() 
    { 
     _mutex.EnterReadLock(); 
     try 
     { 
     return _quotes.ToReadOnly(); 
     } 
     finally 
     { 
     _mutex.ExitReadLock(); 
     } 
    } 

    public void AddQuote() 
    { 
     _mutex.EnterWriteLock(); 
     try 
     { 
     _quotes.Add(quote); 
     } 
     finally 
     { 
     _mutex.ExitWriteLock(); 
     } 
    } 

    public void Dispose() 
    { 
     _mutex.Dispose(); 
    } 
} 

Hoặc nếu bạn đang sử dụng Net 4 hoặc cao hơn có nhiều bộ sưu tập đồng thời sửa đổi tuyệt vời trong the System.Collections.Concurrent namespace mà bạn có thể có thể sử dụng mà không bất kỳ vấn đề nào (chúng là các đối tượng không khóa và thường rất nhanh - và some performance enhancements are coming in .Net 4.5 too!).

+0

Bạn có yêu cầu khóa đọc cả thời gian (đọc/ghi) không? :) –

+0

@AmarPalsapure Cảm ơn, lỗi đánh máy đã được sửa! –

+0

Thx cho câu trả lời của bạn. Tôi sẽ thử khóa để bắt đầu. Bạn nghĩ gì về việc sử dụng dễ bay hơi? –

0

Đó không phải là trường hợp hàng đợi của nhà sản xuất-người tiêu dùng phải không? Người tiêu dùng sẽ đợi (Monitor.Wait) khi Nhà sản xuất chuyển sang xung khi có nguồn cấp dữ liệu mới. Ngay khi nguồn cấp dữ liệu mới/cập nhật xuất hiện, Nhà sản xuất sẽ điền Hàng đợi và kích hoạt Monitor.Pulse.

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