async NamedPipeClientStream实现反馈

时间:2014-04-25 22:44:52

标签: c# asynchronous pipe named

目前,我已使用http://msdn.microsoft.com/en-us/library/bb546085.aspx的演示代码实现了命名管道。而不是同步客户端;但是,我想让它异步。这是我的实现,主程序调用StartClientNamedPipeListening():

    /// <summary>
    /// Buffer where received bytes or bytes received are stored 
    /// </summary>
    private byte[] _byteBuffer = null;

    /// <summary>
    /// Callback result for reading data from the named pipe
    /// </summary>
    private IAsyncResult _pipeResult;

    /// <summary>
    /// Named object to send and receive data to and from watchdog
    /// </summary>
    NamedPipeClientStream _pipeClient;

    /// <summary>
    /// Notifies waiting threads that an event has occurred
    /// </summary>
    protected ManualResetEvent _pipeReadDone = new ManualResetEvent(false);

    private object _pipeState = new object();

    private void StartClientNamedPipeListening()
    {
            // open and then close the gate as soon as after one thread passed,
            // i.e., put the event into a non-signaled, or closed, state:
            _pipeReadDone.Reset();

            // Reads the data coming in from the pipe and call the 
            // thread safe delegate to get the data received.
            _byteBuffer = new Byte[50];
            _pipeResult = _pipeClient.BeginRead(_byteBuffer, 0,
                _byteBuffer.Length, PipeReadCallback, _pipeState);

            // worker thread block in here (waiting for...
            // _pipeReadDone.Set()), i.e., wait for the door to be opened
            _pipeReadDone.WaitOne();            
    }

   private void PipeReadCallback(IAsyncResult ar)
    {
        int bytesRead = 0;

        // if port serial is open and..
        if (_pipeClient.IsConnected)
        {
            // the stream can read then..
            if (_pipeClient.CanRead)
            {
                // wait for asynchronous read to be completed
                bytesRead = _pipeClient.EndRead(ar);
            }
        }

        if (bytesRead > 0)
        {
            StreamString ss = new StreamString(_pipeClient);
            // Validate the server's signature string 
            if (ss.ReadString() == "I am the one true server!")
            {
                // The client security token is sent with the first write. 
                // Send the name of the file whose contents are returned 
                // by the server.
                ss.WriteString(@"C:\Temp\namedpipestring.txt");

                // Print the file to the screen.
                Console.WriteLine(ss.ReadString(), false);
            }
            else
            {
                Console.WriteLine("Server could not be verified.");
            }

            // put the event into a signaled, or open,  state: 
            // open gate for next data
            _pipeReadDone.Set();

            // Start waiting for the next watchdog message
            StartClientNamedPipeListening();
        }
    }

这个实现根据我的测试工作;但是,我想知道,我做了一些明显的禁忌吗?有没有人对如何更好地实施它有任何建议? TIA。

1 个答案:

答案 0 :(得分:0)

以下是我修改代码以使其异步工作的方法。我不确定为什么我认为我需要ManualResetEvent:

    /// <summary>
    /// Buffer where received bytes or bytes received are stored 
    /// </summary>
    private byte[] _byteBuffer = null;

    /// <summary>
    /// Callback result for reading data from the named pipe
    /// </summary>
    private IAsyncResult _pipeResult;

    /// <summary>
    /// Named object to send and receive data to and from watchdog
    /// </summary>
    NamedPipeClientStream _pipeClient;

    private object _pipeState = new object();

    private void StartClientNamedPipeListening()
    {
            _pipeClient = new NamedPipeClientStream(".", "testpipe",
                PipeDirection.InOut, PipeOptions.Asynchronous,
                TokenImpersonationLevel.Impersonation);
            _pipeClient.Connect();
            // Reads the data coming in from the pipe and call the 
            // thread safe delegate to get the data received.
            _byteBuffer = new Byte[50];
            _pipeResult = _pipeClient.BeginRead(_byteBuffer, 0,
                _byteBuffer.Length, PipeReadCallback, _pipeState);      
    }

   private void PipeReadCallback(IAsyncResult ar)
    {
        int bytesRead = 0;

        // if port serial is open and..
        if (_pipeClient.IsConnected)
        {
            // the stream can read then..
            if (_pipeClient.CanRead)
            {
                // wait for asynchronous read to be completed
                bytesRead = _pipeClient.EndRead(ar);
            }
        }

        if (bytesRead > 0)
        {
            StreamString ss = new StreamString(_pipeClient);
            // Validate the server's signature string 
            if (ss.ReadString() == "I am the one true server!")
            {
                // The client security token is sent with the first write. 
                // Send the name of the file whose contents are returned 
                // by the server.
                ss.WriteString(@"C:\Temp\namedpipestring.txt");

                // Print the file to the screen.
                Console.WriteLine(ss.ReadString(), false);
            }
            else
            {
                Console.WriteLine("Server could not be verified.");
            }

            // Start waiting for the next watchdog message
            StartClientNamedPipeListening();
        }
    }

谢谢,汉斯。