2012-01-10 2 views
6

У меня однопроцессорное двухпоточное приложение. В потоке 1 вы услышите фид рыночных данных и обновите последнюю котировку на тысячах акций. В потоке 2 будет запускаться таймер с частотой выборки и сделать снимок последних котировок для обработки. Фактически, мне нужно понизить выборку чрезвычайно быстрого рынка данных.Что такое быстрый, эффективный по памяти способ передачи данных между потоками в C#?

Мое первое предположение заключается в использовании BlockingQueue. Для этого мне нужно переместить функции таймера в Thread 1, что я могу сделать, проверяя часы каждый раз, когда приходит обновление котировки и отправляет моментальный снимок кавычек в очередь на частоте дискретизации. Меня беспокоит то, что очередь будет потреблять много памяти, а сбор мусора замедлит работу.

Мое второе предположение состоит в том, чтобы иметь 1-ю копию данных в заблокированный элемент на частоте дискретизации, к которой может обратиться нить 2. Меня беспокоит, что замки будут медленными.

My thirt Угадайте, чтобы сделать цитаты примитивными нестабильными. Поскольку один поток только пишет и только один поток только читает, возможно, это подходит?

Есть ли способ передачи данных между потоками для этого чувствительного к задержкам приложения? Это не ультра-высокочастотное приложение. Я могу терпеть латентности порядка десятков мс.

ответ

7

Если у вас есть только 2 потоков к этому ресурсу (т.е. одновременно чтения не требуется), то самый простой (и один из самых быстрых) будет просто использовать lock ключевое слово:

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); 
     } 
    } 
} 

Если же требуются параллельные чтения, это было бы хорошо подходит для the ReaderWriterLockSlim class. Вы можете получить блокировку чтения при копировании блокировки записи данных и при записи данных, например:

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(); 
    } 
} 

Или, если вы используете .NET 4 или выше, есть много замечательных одновременно изменяемых коллекций в the System.Collections.Concurrent namespace, которые вы могли бы использовать без любая проблема (они блокируют объекты и, как правило, очень быстрые) и some performance enhancements are coming in .Net 4.5 too!).

+0

Вам потребовалась блокировка чтения и времени (чтение/запись)? :) –

+0

@AmarPalsapure Спасибо, опечатка исправлена! –

+0

Thx для вашего ответа. Я попытаюсь запустить блокировки. Что вы думаете об использовании изменчивости? –

0

Разве это не случай очереди производителя-потребителя? Потребитель будет ждать (Monitor.Wait) после того, как Producer начнет пульсировать, когда появится новый канал. Как только появятся новые/обновленные фиды, Producer заполнит очередь и запустит Monitor.Pulse.

Смежные вопросы