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

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一下就行了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值