2012-01-26 5 views
1

Быстрый вопрос относительно связи между досками arduino и приложением C# winforms. В основном, что я сделал до сих пор, это что-то вродеПоследовательная связь в фоновом режиме

_serialPort = new SerialPort(); 
... 
_serialPort.Open(); 
... 
_serialPort.DataReceived += OnReceived; 
... 
private static void OnReceived(object sender, SerialDataReceivedEventArgs c) 
{ 
// Do something 
} 

Это работает так долго, как я помещал это в главную нить приложения. Мой вопрос в том, можно ли написать класс, который делает то же самое, что и код выше (прослушивание сообщения через serialport) в фоновом потоке.

+2

должен работать, что ломается, когда вы делаете? –

+0

Там мало смысла, DataReceived уже работает в потоке. Другой код ничего не стоит. –

+0

Насколько я могу судить, это прекрасно работает, если вы заранее знаете настройки SerialPort (com, baudrate, buffersize). Я бы предпочел следующее: - показать основную форму - изменить настройки - нажать кнопку и подключиться – JonBlumfeld

ответ

4

Возможно, вы, возможно, при создании экземпляра SerialPort, и все события и операции выполняются на фоне потока только.

Из MSDN:

Любые открытые (Shared в Visual Basic) члены этого типа являются потокобезопасными. Любые члены экземпляра не гарантируют безопасность потоков.

Таким образом, класс не является «Thread Safe», поэтому попытка сделать что-либо в многопоточной манере - не очень хорошая идея.

3

Запуск нового потока для выполнения этого кода не является проблемой. Проблема может возникнуть, если вы используете некоторые данные, созданные потоком, для обновления пользовательского интерфейса приложения. См. Другой вопрос на SO: How to update the GUI from another thread in C#?

1

Я думаю, что это не сработает, потому что в вашем методе OnReceived вы пытаетесь что-то записать в элемент управления графическим интерфейсом (например, TextBox).

Это часть, которая терпит неудачу, а не получение самих данных. Если вы хотите получить доступ к потоку GUI в этом методе, вы должны позвонить [Invoke()][1] или BeginInvoke() о желаемом элементе управления и поместить свой код в заданную лямбду.

Для более продвинутых материалов вы также можете подумать об использовании ReactiveExtensions и метода ObserveOn().

1

У меня есть ответ:

public delegate void DisplayInfoSentDelegate(byte[] abyBuf); 

private void SendThread(_dlg pThis, byte[] abyBuf, int iNumOfBytes) 
{ 
    ... 
    pThis.Invoke(new DisplayInfoSentDelegate(DisplayInListBox), new object[] { abyBuf}); 
} 
Смежные вопросы