第二个线程中的串行通信,异步?

时间:2011-06-01 15:35:21

标签: asp.net c#-4.0

我想将与外部设备的串行通信放到第二个线程c#。

这里有我的第一个线程正在做一些事情。 还有串行工作者,第二个帖子:

  • 打开串口
  • 它会定期询问外部串行设备:你还活着吗?
  • 它接收来自第一个线程的查询,其中包含一个字符串和一个类似于“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 :(得分:0)

我认为thread1和thread2都有自己的“执行”路径,你不能强迫它们“中断”并对你在另一个线程中构建的数据做一些事情。 你可以做的是你“计划”在当前线程中可能需要你注意的另一个线程中有一些准备就绪的可能性。因此,thread1和thread2都需要一个代码来定期检查另一个线程中是否存在“就绪”。 如果你计划在thread1中做其他事情,你仍然需要为thread2的结果进行定期检查/轮询,反之亦然。

线程之间的具体通信可以在每个方向上使用队列来实现。在.NET 4.0中,有一个ConcurrentQueue类,用于线程安全的生产者/消费者实现。当thread1有一个命令时,它应该在命令队列中排队,而thread2应该定期检查是否有命令在等待。当thread2准备好结果时,它应该将它排队到结果队列中,而thread1应该定期检查是否有结果并相应地运行处理代码。

说完这一切之后,我认为你应该再考虑一下,如果你的解决方案正是这两个线程真的是你需要的。但是,这取决于您的要求的细节(例如,同时thread1应该做什么,以及命令结果的处理意味着什么,它可以并行运行等)。

我的建议是根据生产者/消费者模式调整您的设计。这是一个典型的并发任务,你会发现很多解释和优化的解决方案(例如,消费者不必轮询队列,但它可以睡在等待句柄,信号量或其他一些构造而不使用CPU,它可以被生产者唤醒,如果有东西要消费)。 在您的情况下,您可以使用此模式两次。 CommandProducer是创建命令并提供CommandConsumer的实体(可以通过将其传递到串行线来使用它)。在后面的方式中,您有CommandResultProducer读取串行线并将结果传递给CommandResultConsumer以对结果执行某些操作。像这样对齐你的代码会产生一个更加灵活和清晰的解决方案,如果事实证明它是实用的,你甚至可以增加消费者或生产者线程的数量。