Последовательная связь во втором потоке, асинхронно? - PullRequest
0 голосов
/ 01 июня 2011

Я хочу перевести последовательную связь с внешним устройством во второй поток, c #.

Здесь мой первый поток выполняет некоторые вещи.И есть последовательный рабочий, второй поток:

  • Он открывает последовательный порт
  • Он регулярно спрашивает внешнее последовательное устройство: Вы живы?
  • Он получает запросы из первого потока со строкой и значением типа int: «Command2», 33, и должен передавать это внешнему последовательному устройству.
  • Иногда приходит ответ отвнешнее последовательное устройство возвращается со строкой и int типа: «Command4», 55 и второй поток должен передать это первому потоку, и он должен начать процесс там.
  • Второй поток также имеет собственные вещи, такие какобнаружение ошибок, которое я хочу оставить свободным в первом потоке.

Сам последовательный обмен данными работает нормально, но у меня проблемы с потоками, делегатами, BeginInvokes, EventHandlers и т. д.

Мой первыйпоток:

Class MainProgramme
{
internal void StartSerialCommunication
{
=> Here I want the second thread to open the serial port and I want to start the regulary serial device check, all in the 
second thread.
}
internal bool SerialCommand(string s, int i)
{
=> Here I want to give the command s and i to the second thread asynchronously. That means this process does not wait for an answer from the second thread.
}

Второй процесс должен быть запущен вторым потоком, поскольку второй поток получил некоторые важные данные от внешнего последовательного устройства.

internal void SerialAnswered
{
=> Here I want to get the string and the int from the second device back.
}
}

Мой второй поток:

Class SerialCommunication
{
internal bool SerialDeviceIsAlive = true;
public bool SerialOpen

{   
SerialPortMsp.Open();
RegularyDeviceCheckTimer.Enabled = true;
return true;
}

private void RegularyDeviceCheckTimer_Tick(System.Object 

sender, System.EventArgs e)
{
if SerialDeviceIsAlive == true)
{ 
SerialDeviceIsAlive == false;
}
else
{
=> Here I want to inform the first thread that the answer from the external serial device is missing.
}
SerialSend("AreYouAlive");
}

public void SerialReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{ 
IAmAlive = true;
int buff = SerialPortMsp.ReadExisting();
if (buff.IndexOf(new string('\n', 1)) > 0)
{
=> Here I want to inform the first thread that the answer was buff.
}
}

public bool SerialSend(string SerialCommand) 
{
SerialPortMsp.Write(SerialCommand.ToCharArray(), 0, 

SerialCommand.Length);
return true;    
}
}

Мне нужна помощь в вызове процессов и передаче данных между двумя потоками.

1 Ответ

0 голосов
/ 02 июня 2011

Я думаю, что и thread1, и thread2 имеют свой «собственный» путь выполнения, и вы не можете заставить их «прерывать» и что-то делать с данными, которые вы создали в другом потоке.Что вы можете сделать, так это то, что вы «планируете» возможность того, что в другом потоке есть что-то готовое, что может потребовать вашего внимания в текущем потоке.Следовательно, и thread1, и thread2 нужен код, который регулярно проверяет, есть ли что-то «готовое» в другом потоке.Если вы планируете делать что-то другое в потоке 1, вам все равно необходимо встроить регулярную проверку / опрос результатов thread2 и наоборот.

Конкретное взаимодействие между потоками может быть реализовано с очередью в каждом направлении.,В .NET 4.0 есть класс ConcurrentQueue для поточно-ориентированной реализации производителя / потребителя.Когда у thread1 есть команда, он должен ставить ее в очередь команд, а thread2 должен регулярно проверять, есть ли ожидающие команды.Когда у thread2 есть готовый результат, он должен поставить его в очередь результатов, в то время как thread1 должен регулярно проверять, есть ли результат, и запускать код обработки соответствующим образом.Более того, если ваше решение именно с этими двумя потоками действительно то, что вам нужно.Однако это зависит от деталей ваших требований (например, что еще должен делать thread1 в то же время, и что означает обработка результата команды, может ли он выполняться параллельно и т. Д.).

Мое предложение будетвыровнять свой дизайн на основе модели производителя / потребителя.Это типичная задача параллелизма, и вы найдете множество объяснений и оптимизированных решений (например, когда потребителю не нужно опрашивать очередь, но он может спать на ручке ожидания, семафоре или какой-либо другой конструкции без использования ЦП и можетбыть разбуженным производителями, если есть что потреблять).В вашем случае вы можете использовать этот шаблон дважды.CommandProducer - это объект, который создает команды и передает CommandConsumer (который может потреблять его, передавая его в последовательную линию).На обратном пути у вас есть CommandResultProducer, который читает последовательную строку и передает результат в CommandResultConsumer, чтобы что-то сделать с результатом.Такое выравнивание вашего кода приведет к более гибкому и понятному решению, и вы даже можете увеличить количество потоков потребителя или производителя, если это окажется практичным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...