异步调用机制设计c#

时间:2011-05-11 05:31:37

标签: c# multithreading asynchronous

要求是从硬件上连续读取数据并将数据发送到 上层用于进一步处理。

目前我使用同步机制。即 请求 - >等等 - >阅读--->发送处理。

    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并停止循环(从硬件读取也是如此)

既然我需要在代码中实现一些并行性以提升性能,我想学习以异步方式完成阅读的方式来改进它。

那里的任何人都会帮助我改进现有的设计。

提前致谢

3 个答案:

答案 0 :(得分:2)

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

  1. Asynchronous Programming Model
  2. Event-based asynchronous programming model
  3. Task parallel library(.NET 4.0)
  4. 对于你明显的低级别代码,我会选择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

还包含一个如何使用它的好例子。

希望这有帮助