C#异步调用机制设计

发布于 2024-11-06 04:58:24 字数 2608 浏览 1 评论 0原文

需求是不断地从硬件中读取数据并将数据发送到 上层进行进一步处理。

目前我使用同步机制。 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

洒一地阳光 2024-11-13 04:58:24

通常,在 .NET 中执行异步工作有三种常见模式:

  1. 异步编程模型< /a>
  2. 基于事件的异步编程模型
  3. 任务并行库(.NET 4.0)

对于您明显的低级代码片段,我会选择 1 或 3,因为 2 通常用于更高级别的组件。

一般设计将使用上述任何一种方式在单独的线程中执行循环,当循环完成时通知调用线程操作已完成,并传递结果(在您的情况下,这应该是 < code>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;
}

Generally there are three common patterns to do asynchronous work in .NET:

  1. The Asynchronous Programming Model
  2. The Event-based asynchronous programming model
  3. The Task parallel library (.NET 4.0)

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:

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;
}
诗化ㄋ丶相逢 2024-11-13 04:58:24

我认为你的设计可以通过使用异步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 a Stream in there somewhere. Instead of calling Read (which is synchronous) you would use BeginRead 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.

↘紸啶 2024-11-13 04:58:24

有一个称为后台工作程序的 .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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文