C#学习笔记(2):多线程数据交换

来源:互联网 发布:js给字符串加密 编辑:程序博客网 时间:2024/05/21 15:07

C#中可以通过管道流实现多线程之间数据交换。C#的管道氛围服务器端和客户端,二者均可配置为输入/输出/双向。服务器管道流监听客户管道流的连接请求。通常是一个线程间里服务器管道流,另一个线程建立客户管道流。二者建立连接之后,一条位于两个线程之间的管道流就形成了。

服务器管道流的使用线程代码示例片段如下:

   class ServerThread   {      public ServerThread(string pipeName)      {         pipedStream = new NamedPipeServerStream(pipeName);      }      public void run()      {         Console.WriteLine(">> SERVER_THREAD: waiting for client connection ...");         pipedStream.WaitForConnection();         Console.WriteLine("  done.");         byte[] buffer = new byte[BUFFER_LENGTH];         int readCount;         do {            readCount = pipedStream.Read(buffer, 0, BUFFER_LENGTH);            if (readCount > 0)            {               string recvMsg = new String(System.Text.Encoding.Default.GetChars(buffer, 0, readCount));               Console.WriteLine(">> SERVER_RECV: " + recvMsg);               byte[] sendData = System.Text.Encoding.Default.GetBytes("SERVER_RETURN: " + recvMsg);               pipedStream.Write(sendData, 0, sendData.Length);            }         } while(readCount > 0);      }      public void stop()      {         pipedStream.Close();         pipedStream.Dispose();         pipedStream = null;      }      private NamedPipeServerStream pipedStream;      private const int BUFFER_LENGTH = 1024;   }

客户端管道流使用代码示例片段如下:

   class ClientThread   {      public ClientThread(string pipeName)      {         pipedStream = new NamedPipeClientStream(pipeName);      }      public void run()      {         Console.Write(">> CLIENT_THREAD: connecting to server pipe stream ...");         pipedStream.Connect();         Console.WriteLine("  done.");         byte[] buffer = new byte[BUFFER_LENGTH];         int loopCount = 1;         int readCount;         do         {            string sendMsg = "CLIENT_SEND: the loop count is: " + loopCount;            byte[] sendData = System.Text.Encoding.Default.GetBytes(sendMsg);            pipedStream.Write(sendData, 0, sendData.Length);            loopCount++;            readCount = pipedStream.Read(buffer, 0, BUFFER_LENGTH);            if (readCount > 0)            {               string recvMsg = new String(System.Text.Encoding.Default.GetChars(buffer, 0, readCount));               Console.WriteLine(">> CLIENT_RECV: " + recvMsg);            }         } while (loopCount <= 5);         stop();      }      public void stop()      {         pipedStream.Close();         pipedStream.Dispose();         pipedStream = null;      }      private NamedPipeClientStream pipedStream;      private const int BUFFER_LENGTH = 1024;   }

主程序代码如下:

   class MultiThreadExchange   {      public void run()      {         Console.Write("creating thread ...");         ServerThread serverThreadInstance = new ServerThread(pipeName);         Thread serverThread = new Thread(new ThreadStart(serverThreadInstance.run));         serverThread.Start();         ClientThread clientThreadInstance = new ClientThread(pipeName);         Thread clientThread = new Thread(new ThreadStart(clientThreadInstance.run));         clientThread.Start();         Console.WriteLine("  done.");      }      private const string pipeName = "testPipe";   }

程序运行后,输出结果如下:

creating thread ...>> SERVER_THREAD: waiting for client connection ...  done.>> CLIENT_THREAD: connecting to server pipe stream ...  done.  done.>> SERVER_RECV: CLIENT_SEND: the loop count is: 1>> CLIENT_RECV: SERVER_RETURN: CLIENT_SEND: the loop count is: 1>> SERVER_RECV: CLIENT_SEND: the loop count is: 2>> CLIENT_RECV: SERVER_RETURN: CLIENT_SEND: the loop count is: 2>> SERVER_RECV: CLIENT_SEND: the loop count is: 3>> CLIENT_RECV: SERVER_RETURN: CLIENT_SEND: the loop count is: 3>> SERVER_RECV: CLIENT_SEND: the loop count is: 4>> CLIENT_RECV: SERVER_RETURN: CLIENT_SEND: the loop count is: 4>> SERVER_RECV: CLIENT_SEND: the loop count is: 5>> CLIENT_RECV: SERVER_RETURN: CLIENT_SEND: the loop count is: 5

需要注意的是:NamedPipeServerStream.WaitForConnection()和NamedPipeClientStream.Connect()操作都是阻塞操作,在完成服务器端和客户端的管道连接之前,执行这两个函数的线程会被一直阻塞。感觉这就像网络连接一样。不明白MS为什么要把C#的管道流设计成这样,用起来这么麻烦,可能是考虑与Windows的管道API对应吧。

个人还是比较喜欢Java的管道流的操作方式,分别创建输入管道流对象和输出管道流对象,然后把两个管道流connect一下就行了。

原创粉丝点击