2013-05-28 2 views
1

У меня событие несколько раз. Каждая стрельба порождает поток, который обрабатывает вход, и эта обработка должна быть последовательной.C#: Управление очередью ожидания потока

Это код:

void TcpClient_DataRead(object sender, DataReadEventArgs e) 
    { 
     //the first stops the other ones 
     this.parsingXML.WaitOne(); 
     //processing the string 
     string pop = Encoding.ASCII.GetString(e.Data); 
     BufferizeXML(pop); 
     //restoring execution 
     this.parsingXML.Set(); 
    } 

Здесь я попытался сделать другую нить ждать и восстановления после выполнения предыдущей закончилась, но это решение восстановить все нити ожидания.

Есть ли способ управления очередью ожидания потока?

+2

Звучит как прекрасная работа для TPL DataFlow: http://msdn.microsoft.com/en-us/library/hh228603.aspx – spender

ответ

5

Это типичный случай, когда вы можете использовать шаблон publish-consumer. Вы можете использовать Queue<T> или ConcurrentQueue<T> для очереди событий, а затем удалить один поток и выполнить фактическую обработку. Вам просто нужен один поток, так как вы сказали, что их нужно выполнять последовательно, это позволит избежать времени при создании потоков. Просто следите за тем фактом, что вы должны заблокировать доступ к очереди, если вы не можете (в основном потому, что вы вынуждены использовать более старую версию фреймворка) использовать параллельную версию.

+2

+1, да, а также избегайте потокового микроуправления, что новички всегда ошибаются , и те, у кого больше опыта, никогда не пытаются. К сожалению, OP, похоже, прочитал одну из многих, восхитительных книг/сайтов «Введение в потоки», которые, как всегда, начинаются с непрерывного создания потоков и ожидания их завершения с помощью join() или любого другого. Как я уже неоднократно публиковал, авторы этих материалов должны быть привязаны к колу, их книги/распечатки сложенные и применяется факел. –

0

Запустить задачу при инициализации приложения, создать параллельную очередь, запустить задачу чтения данных и связать обработчик события после нее.

ConcurrentQueue<DataReadEventArgs> list; 
Init() 
{ 
    var list = new ConcurrentQueue<DataReadEventArgs>(); 
    Task.Factory.StartNew(()=>DataRead()); 
    OnTcpClientDataRead += TcpClient_DataRead; 
} 

// ИЗДАТЕЛЬ

void TcpClient_DataRead(object sender, DataReadEventArgs e) 
{ 
    list.Enqueue(e); 
} 

всегда работает работа, какой процесс BufferizeXml для всех данных в очереди, если список пуст, берет паузу секунды и продолжить снова // ПОТРЕБИТЕЛЬСКИХ

void DataRead() 
{ 
    while(true) 
    { 
    if (list.Count ==0) 
    Thread.Sleep(1000); 

    string pop; 
    list.TryDequeue(out pop); 
    Encoding.ASCII.GetString(pop); 
    BufferizeXML(pop); 
    } 
} 

Вы можете поместить некоторую переменную, и пусть цикл while проверяет ее на нарушение итерации.

+0

Что произойдет, если TcpClient_DataRead будет доступен одновременно двумя потоками? В этом случае вы не будете работать, вам нужно инициализировать его с самого начала. –

+1

@FelixK. Я изменил код. –

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