Presently, I have implemented named pipes using demo code from http://msdn.microsoft.com/en-us/library/bb546085.aspx . Instead of the synchronous client; however, I want to make it asynchronous. Here is my implementation, where the main program makes a call to 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();
}
}
This implementation works according to my tests; however, I was wondering, am I doing some obvious no-no's? Does anyone have any suggestions on how it could possibly be implemented better? TIA.
Here is how I modified the code to get it to work asynchronously. I'm not sure why I thought I needed the 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();
}
}
Thanks, Hans.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.