2013-05-02 3 views
0

Я не знаю, если это хороший способ работать со стеком для этой задачи, но я уверен, что существует более быстрый способ ... Я получаю данные от своего микроконтроллера, но длина данных не всегда одинаковой длины. Я подумал, что, может быть, я могу нажимать данные в своем стеке, и в потоке я могу поместить его и декодировать сообщение. Я не хотел замедлять DataReceivedHandler, поэтому я создал Thread, который может вытолкнуть данные и записать их в мой Listview в моей функции decodeMessage().Последовательный порт чтения + Нитки или что-то еще лучше?

Через некоторое время я получаю исключение System.OutOfMemories ..

Любые идеи, как я могу сделать это в лучшую сторону?

Я читаю от моего последовательного порта только тогда, когда данные поступают сюда:

Stack<byte[]> stack = new Stack<byte[]>(); 

.....

public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort sp = (SerialPort)sender; 
    byte[] data = new byte[sp.BytesToRead]; 
    sp.Read(data, 0, data.Length); 

    stack.Push(data); 
} 

И это моя тема:

private void formatData() 
{ 
    try 
    { 
     while (true) 
     { 
      byte[] data; 
      int i=0; 

      Dispatcher.BeginInvoke(new Action(() => 
      { 
       while (stack.Count > 0) 
       { 
        data = stack.Pop(); 
        while (i < data.Length) 
        { 
         decodeMessage(data[i]); 
         i++; 
        } 
       } 
      }));   
     } 
    } 
    catch (Exception ex) 
    { 
     System.Windows.Forms.MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
} 

thx

+0

Кажется, вам нужно [BlockingCollection] (http://msdn.microsoft.com/en-us/library/dd267312.aspx) вместо 'Stack' – I4V

+6

Я не думаю, что стек, что вы want, Queue, вероятно, более подходит для этого, так как это FIFO. BlockingCollection, как было предложено выше, использует очередь по умолчанию и является потокобезопасной. Реализация стека не является потокобезопасной, что может вызвать проблемы. –

+0

Но как я знаю, сколько Элементов я должен прочитать через Очередь? – user2261524

ответ

3

Этот код использует нить безопасная очередь. Я упростил часть своего собственного кода, поэтому этот код не тестируется и не компилируется. Если у вас возникли проблемы с компиляцией или возникают ошибки, добавьте комментарий ко мне, и я помогу вам.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO.Ports; 
using System.Windows.Threading; 
using System.Collections.Concurrent; 

void someRoutine() 
{ 
    // initialize queue before using it 
    serialDataQueue = new ConcurrentQueue<char>(); 

} 


/// <summary> 
/// data from serialPort is added to the queue as individual chars, 
/// a struct may be better 
/// </summary> 
public ConcurrentQueue<char> serialDataQueue; 

// get data 
void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort sp = sender as SerialPort; 
    int bytesAvailable = sp.BytesToRead; 

    // array to store the available data  
    char[] recBuf = new char[bytesAvailable]; 

    try 
    {  
     // get the data 
     sp.Read(recBuf, 0, bytesAvailable); 

     // put data, char by char into a threadsafe FIFO queue 
     // a better aproach maybe is putting the data in a struct and enque the struct   
     for (int index = 0; index < bytesAvailable; index++) 
      serialDataQueue.Enqueue(recBuf[index]); 

    } 
    catch (TimeoutException ex) 
    { 
     // handle exeption here 
    } 
} 



/// <summary> 
/// Check queue that contains serial data, call this 
/// routine at intervals using a timer or button click 
/// or raise an event when data is received 
/// </summary> 
private void readSearialDataQueue() 
{ 
    char ch; 

    try 
    { 
     while (serialDataQueue.TryDequeue(out ch)) 
     { 
      // do something with ch, add it to a textbox 
      // for example to see that it actually works 
      textboxDataReceived.Text += ch; 
     } 

    } 
    catch (Exception ex) 
    { 
     // handle ex here 
    } 
}