要求是从硬件上连续读取数据并将数据发送到 上层用于进一步处理。
目前我使用同步机制。即 请求 - >等等 - >阅读--->发送处理。
do
{
int ix = iy;
iy = 0;
if(ix<1)
{
while (((ix = ReadSst(ref sBuffer)) < 1) && bProcessNotEnded == true)
{
if (ix < 0) // BT Error
{
eErr = CError.BUFF_KILL; //Throw error and exit
break;
}
Thread.Sleep(2);
iTimeOut += 2;
if (iTimeOut > TIMEOUT_2000)
{
eErr = CError.TIMEOUT_ERR;
objLogger.WriteLine("HW TIMED OUT");
break;
}
}
}
iBytesRead = ix;
if (iBytesRead <= 0)
{
eErr = CError.READ_ERR;
objLogger.WriteLine("READ ERROR");
break;
}
sReadMsg = sReadMsg + sBuffer;
if(sReadMsg.Length >0)
iEndPos = sReadMsg.IndexOf('\n',1);
else
iEndPos = -1;
if (sReadMsg.Length > 2)
{
if ((iEndPos == 0 && sReadMsg[0] == '\n') || (iEndPos > 0 && sReadMsg[sReadMsg.Length - 1] == '\n' && sReadMsg[sReadMsg.Length - 2] == '\r')) //finished
{
Thread.Sleep(50); // wait a short time to be sure there that there is no further input
if (sReadMsg.Length >= 3 && sReadMsg[sReadMsg.Length - 3] == 'a')
continue;
iy = ReadSst(ref sBuffer);
if (iy == 0)
{
bProcessNotEnded = false;
objLogger.WriteLine("bProcessNotEnded is made false, End of frame detected");
break;
}
else if (iy < 0)
{
eErr = CError.BUFF_KILL; // error
break;
}
}
}
} while (bProcessNotEnded);
ReadSst方法是对硬件的调用以请求数据。
从代码中可以看出,当前逻辑i循环读取直到bProcessNotEnded标志为真。一旦在我收到的字符串缓冲区中检测到帧结束,我将标志设置为false并停止循环(从硬件读取也是如此)
既然我需要在代码中实现一些并行性以提升性能,我想学习以异步方式完成阅读的方式来改进它。
那里的任何人都会帮助我改进现有的设计。
提前致谢
答案 0 :(得分:2)
通常,在.NET中进行异步工作有三种常见模式:
对于你明显的低级别代码,我会选择1或3,因为2通常用于更高级别的组件。
要使用的一般设计将使用上述任何方式在单独的线程中执行循环,并且当循环完成时通知调用线程操作已完成,传递结果(在您的情况下,这应该是sReadMsg
的内容以适当的方式(取决于您选择的方式)。
这是一个简短的例子,说明如何使用TPL轻松完成:
private void ReadMessageAsync()
{
// Set up the task to read the message from the hardware device.
Task<string> readMessageTask = new Task<string>(ReadMessage);
// Set up the task to process the message when the message was read from the device.
readMessageTask.ContinueWith(ProcessMessage);
// Start the task asynchronously.
readMessageTask.Start();
}
private void ProcessMessage(Task<string> readMessageTask)
{
string message = readMessageTask.Result;
// Process the message
}
private string ReadMessage()
{
string message = string.Empty;
// Retrieve the message using your loop
return message;
}
答案 1 :(得分:1)
我认为使用异步IO可以改善您的设计。我们没有看到ReadSst
是如何实现的,但我怀疑你在某处使用了Stream
。而不是调用Read
(同步),而是使用BeginRead
代替(这是异步的)。此更改将导致代码设计中的其他更重要的更改。我将首先研究异步IO并尝试自己实现,然后发布后续问题,如果它们是我们可以帮助的更具体的问题。
答案 2 :(得分:0)
有一个名为Background worker的.net组件,您可以将循环处理放在'DoWork'事件中,同时保持应用程序的响应。
这是暴露它的类:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28v=VS.90%29.aspx
还包含一个如何使用它的好例子。
希望这有帮助