【发布时间】:2016-05-28 18:04:05
【问题描述】:
我有一个通过串行端口与微控制器通信的应用程序。我想在后台工作人员中定期检查控制器的状态,并允许用户通过发送命令和接收响应来异步(通过用户界面)与控制器交互。
UI 和 Background Worker 使用 SerialCommunication 静态类:
static class SerialCommunication
{
static SerialPort serialPort;
static int readWriteTimeout = 1000; // [ms]
static int waitForTransmissionTimeout = 2; // [s]
static string rxData = "", endOfString = "" + char.MinValue;
static bool WaitingForSerialData = false; // Set in SerialWrite(), cleared in SerialRead()
[...]
public static string SerialRead()
{
try
{
rxData = serialPort.ReadTo(endOfString);
}
catch (TimeoutException)
{
WaitingForSerialData = false;
throw new Exception(Properties.Resources.serial_read_timeout);
}
WaitingForSerialData = false;
return rxData;
}
public static void SerialWrite(string text)
{
DateTime start = DateTime.Now;
while (WaitingForSerialData) // Avoids the situation in which a command executed on a thread receives the response for the command executed from a different thread
{
if (!WaitingForSerialData)
{
try
{
WaitingForSerialData = true; // All commands wait for confirmation/data, so it is normal to set this boolean value for every serial transmission
serialPort.Write(text);
}
catch (TimeoutException)
{
throw new Exception(Properties.Resources.serial_write_timeout);
}
}
else
{
System.Threading.Thread.Sleep(100);
if ((DateTime.Now - start).Seconds >= waitForTransmissionTimeout)
{
throw new Exception("Timeout");
}
}
}
}
}
串口在应用程序启动时初始化。 SerialWrite 和 SerialRead 在 UI 或 Background Worker 中连续调用。
我想避免命令接收来自在不同线程中执行的另一个命令的响应的情况。目前,我已经在发送命令之前在 SerialWrite 中等待接收命令(以便 SerialRead 完成),但如果 SerialWrite 是,我担心这会阻塞 UI(最多 waitForTransmissionTimeout 秒)从那里执行。
那么同步 SerialPort 操作的最佳方式是什么?
【问题讨论】:
-
那么,所有命令都是 SerialWrite 后跟 SerialRead 来接收响应?如果是这样,为什么不在单个 SendCommand 或其他东西中结合读取和写入操作?
-
@Evk 但是如果 SendCommand 被执行会发生什么,例如,在后台工作线程中,以及在 UI 中执行之后(完成执行之前)?
-
你应该用简单的锁来保护整个操作(写+读)。然后,如果 UI 在后台工作人员完成执行之前发送命令 - 它会等到它完成。当然,无论如何您都不应该从 UI 线程执行该操作。从后台线程执行它,然后在完成后将结果分派回 UI 线程(向用户显示结果)。永远不要直接在 UI 线程上执行这样的事情。
-
@Evk 你能给出一个代码示例吗?
标签: c# wpf multithreading serial-port synchronization