2013-06-29 3 views
0

У меня есть класс JournalService, который собирает записи, поступающие на события. Класс собирает записи в списке. События происходят из нескольких потоков. В листе списка записей есть предел. Я использую .NET 4.0. Чтобы сделать его потокобезопасным, я блокирую чтение и запись доступа к списку «записей». У меня нет опыта в этом вопросе, и я не уверен, что делаю это хорошо. Возможно, мне нужно использовать System.Collections.Concurrent NamespaceЗапись из нескольких потоков, .NET 4

Мой вопрос: нужен ли мне ремонт моего кода и какой параллельный класс использовать и как?

Текущий код:

public class JournalService : IJournalService 
{ 
    private readonly List<JournalRecord> records = new List<JournalRecord>(); 
    private readonly ISettings settings; 

    public JournalService(IEventAggregator eventAggregator, ISettings settings) 
    { 
     if (eventAggregator == null) throw new ArgumentNullException("eventAggregator"); 
     if (settings == null) throw new ArgumentNullException("settings"); 

     this.settings = settings; 
     eventAggregator.JournalRecordPosted += EventAggregator_JournalRecordPosted; 
    } 

    public IEnumerable<JournalRecord> GetRecords() 
    { 
     JournalRecord[] tempRecords; 
     lock (records) 
     { 
      tempRecords = records.ToArray(); 
     } 
     return tempRecords; 
    } 

    private void EventAggregator_JournalRecordPosted(object sender, JournalRecordEventArgs e) 
    { 
     lock (records) 
     { 
      int surplus = records.Count - settings.TradeJournalLength; 
      if (surplus == 0) 
       records.RemoveAt(0); 
      else if (surplus > 0) 
       records.RemoveRange(0, surplus); 
      records.Add(e.Record); 
     } 
    } 
} 

EDIT: расчет Излишки положить внутрь замка. EDIT: Добавлена ​​проверка на излишек == 0.

+1

Расчет излишек должно быть сделано * внутри * замок. В противном случае он появляется в «Thread Safe». Если это не узкое место, я не понимаю, почему его нужно «ремонтировать» в качестве параллелизма, хотя границы списка (при использовании в качестве FIFO) являются нелепыми, поскольку это связано с несколькими ходами. (Возможно, [Queue] (http://msdn.microsoft.com/en-us/library/7977ey2c.aspx) было бы лучше и не касалось одновременного: D) – user2246674

+0

Вы просто пытаетесь сохранить последние N записи? Например, вы хотите сохранить только последние 100 или 1000 записей? –

+0

Джим - Да, мне нужны только последние N записей. user2246674 - Я положил излишек в замок. –

ответ

0

Вы можете использовать ConcurrentQueue с замком бесплатно

private int _length = 0; 
private void EventAggregator_JournalRecordPosted(object sender, JournalRecordEventArgs e) 
{ 
    records.Enqueue(e.Record); 


    if(Interlocked.Increment(ref _length)>=settings.TradeJournalLength) 
    while(!records.Dequeue()) 
    { 

    } 
Interlocked.Decrement(ref _length) 
} 
0

Используйте ConcurrentQueue:

private void EventAggregator_JournalRecordPosted(object sender, JournalRecordEventArgs e) 
{ 
    records.Enqueue(e.Record); 

    if (records.Count >= settings.TradeJournalLength) 
    { 
     recordType temp = null; 
     records.TryDequeue(out temp); 
    } 
}