【发布时间】:2021-01-24 19:22:51
【问题描述】:
我正在编写一个运行脚本插件的应用程序,以自动化用户过去必须通过串行终端手动执行的操作。所以,我基本上是在代码中实现串行终端的功能。终端的功能之一是发送一个命令,该命令启动终端从设备接收连续流数据,直到用户按下空格键,然后停止数据流。在数据流式传输时,用户将在其他设备上的另一个应用程序中设置一些值,并观察终端中流式传输的数据变化。
现在,流数据可以采用不同的形式,具体取决于发送的特定命令。例如,一个响应可能如下所示:
---RESPONSE HEADER---
HERE: 1
ARE: 2 SOME:3
VALUES: 4
---RESPONSE HEADER---
HERE: 5
ARE: 6 SOME:7
VALUES: 8
....
另一个可能看起来像:
here are some values
in cols and rows
....
所以,我的想法是根据我发送的命令使用不同的解析器。所以,我做了以下事情:
public class Terminal
{
private SerialPort port;
private IResponseHandler pollingResponseHandler;
private object locker = new object();
private List<Response1Clazz> response1;
private List<Response2Clazz> response2;
//setter omited for brevity
//get snapshot of data at any point in time while response is polling.
public List<Response1Clazz> Response1 {get { lock (locker) return new List<Response1Clazz>(response1); }
//setter omited for brevity
public List<Response2Clazz> Response2 {get { lock (locker) return new List<Response1Clazz>(response2); }
public Terminal()
{
port = new SerialPort(){/*initialize data*/}; //open port etc etc
}
void StartResponse1Polling()
{
Response1 = new List<Response1Clazz>();
Parser<List<Response1Clazz>> parser = new KeyValueParser(Response1); //parser is of type T
pollingResponseHandler = new PollingResponseHandler(parser);
//write command to start polling response 1 in a task
}
void StartResponse2Polling()
{
Response2 = new List<Response2Clazz>();
Parser<List<Response2Clazz>> parser = new RowColumnParser(Response2); //parser is of type T
pollingResponseHandler = new PollingResponseHandler(parser); // this accepts a parser of type T
//write command to start polling response 2
}
OnSerialDataReceived(object sender, Args a)
{
lock(locker){
//do some processing yada yada
//we pass in the serial data to the handler, which in turn delegates to the parser.
pollingResponseHandler.Handle(processedSerialData);
}
}
}
类的调用者将类似于
public class Plugin : BasePlugin
{
public override void PluginMain()
{
Terminal terminal = new Terminal();
terminal.StartResponse1Polling();
//update some other data;
Response1Clazz response = terminal.Response1;
//process response
//update more data
response = terminal.Response1;
//process response
//terminal1.StopPolling();
}
}
我的问题很笼统,但我想知道这是否是处理这种情况的最佳方法。现在我需要传入一个我想要修改的对象/列表,它是通过副作用修改的。出于某种原因,这感觉有点难看,因为代码中确实没有迹象表明这是正在发生的事情。我这样做纯粹是因为“开始”方法是知道要创建哪个解析器以及要更新哪些数据的位置。也许这是犹太洁食,但我认为值得询问是否有另一种/更好的方法。或者至少是一种更好的方式来表明“Handle”方法会产生副作用。
谢谢!
【问题讨论】:
标签: c# parallel-processing side-effects