C#异步调用机制设计
需求是不断地从硬件中读取数据并将数据发送到 上层进行进一步处理。
目前我使用同步机制。 IE 请求-->等等-->阅读--->发送以供处理。
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 方法是对硬件的调用以请求数据。
从代码中可以看出,当前逻辑循环并读取,直到 bProcessNotEnded 标志为 true。一旦在我接收的字符串缓冲区中检测到帧结尾,我将标志设置为 false 并且循环停止(从硬件读取也是如此)
现在我需要在代码中实现一些并行性以提高我想要的性能学习以异步方式完成阅读的方式改进它。
任何能帮助我改进现有设计的人。
提前致谢
The requirement is to continuosly read the data from a hardware and send the data to the
upper layers for further processing.
Presently i use the synchronous mechanism. i.e
Request --> Wait --> Read ---> Send for processing.
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);
The ReadSst method is a call made to the hardware to request the data.
As seen from the code, the present logic i loop and read till the bProcessNotEnded flag is true. Once the end of frame is detected in the string buffer i receive, i set the flag to false and the looping is stopped (so is the reading from the hardware)
Now that i need to achieve some parallelism in my code to boost performance i want to learn to improve it in a way the reading is done in asynchronous fashion.
Anyone out there who's gonna help me in improving this existing design.
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
通常,在 .NET 中执行异步工作有三种常见模式:
对于您明显的低级代码片段,我会选择 1 或 3,因为 2 通常用于更高级别的组件。
一般设计将使用上述任何一种方式在单独的线程中执行循环,当循环完成时通知调用线程操作已完成,并传递结果(在您的情况下,这应该是 < code>sReadMsg)以适当的方式(取决于您选择的方式)。
下面是一个简短的示例,说明您可以如何轻松地使用 TPL 来完成此操作:
Generally there are three common patterns to do asynchronous work in .NET:
For your obviously low-level piece of code I would go for 1 or 3, as 2 is usually used on higher level components.
The general design to go for would to execute your loop in a separate thread using any of the above ways and when the loop is finished notifying the calling thread that the operation completed, passing the result (in your case this should be the content of
sReadMsg
) in an appropriate way (depends on which way you choose).Here is a short example on how easily you could do it using TPL:
我认为你的设计可以通过使用异步IO来改进。我们没有看到 ReadSst 是如何实现的,但我怀疑您在某处使用了 Stream 。您可以使用
BeginRead
(异步),而不是调用Read
(同步)。这一变化将导致代码设计方面的其他更重大的变化。我会首先研究异步 IO 并尝试自己实现,然后发布后续问题(如果这些问题是我们可以帮助解决的更具体问题)。I think your design could be improved by using asynchronous IO. We did not see how
ReadSst
was implemented, but I suspect you are using aStream
in there somewhere. Instead of callingRead
(which is synchronous) you would useBeginRead
instead (which is asynchronous). This change will lead to other more significant changes in the design of the code. I would start by researching asynchronous IO and attempt an implementation yourself and then post follow up questions if their are more specific issues we can help with.有一个称为后台工作程序的 .net 组件,您可以将循环处理放在 'DoWork' 事件中,同时保持应用程序响应。
下面是公开它的类:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28v=VS.90%29.aspx
还包含如何使用它的一个很好的示例。
希望这有帮助
There is a .net component called Background worker, you can put the loop processing in the 'DoWork' event and keep your application responsive at the same time.
Here is the class that exposes it:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28v=VS.90%29.aspx
Also contains a good example of how to use it.
Hope this helps