C# 使用多线程如何传递两个以上参数的实现方法(附示例)

开发 后端
某些情况下当我们启动一个线程的时候会向该线程传递参数,有时除了功能上需要之外,我觉得还有就是为了我们能管理好启动的线程组(当然,只开一两个线程什么的也谈不上不好管理了,我说的线程组是指10+的线程,我们很难去主动控制的)。

某些情况下当我们启动一个线程的时候会向该线程传递参数,有时除了功能上需要之外,我觉得还有就是为了我们能管理好启动的线程组(当然,只开一两个线程什么的也谈不上不好管理了,我说的线程组是指10+的线程,我们很难去主动控制的)。

因为刚接触C#,所以还没有在C#下用过多线程去实现某些功能。通过学习我发现单纯的去启动线程很容易,反而是想要往线程中传一些参数变得有点说道了,这里我想说传入参数的数量为>=2。不过我们还是一步一步的来,带大家过一遍C#下的多线程怎么搞。

以上一篇讲的网络通信的例子,把整个过程走一遍。这里网络通信只是作为一个讲解的示例,依旧是在控制台(Console)程序下实现的。

当Server端想要能与多个Client端进行连通的话,就必须用到多线程机制,我的思路:当程序启动后,Server端自己开一个专门用于进行监听的线程,这样主程序如果想做其他事也就不耽误了。当监听线程检测到有连接的请求,就为这个IP单***建一个新的Socket(我们暂时称为SA Socket)进行通信用,当然,这个SA通信的内容(比如:收发消息)就是在一个新的线程或者两个(我们暂时称为TA线程)里实现的了,这个时候就需要我们往TA线程里传入SA的专有ID,让TA线程只专门为SA服务。之后的就依次类推了。

下面创建一个监听线程,这也是一个C#下最简单的多线程使用——创建多线程

  1. Thread ListenThread = new Thread(new ThreadStart(ServerListener));   
  2. ListenThread.Start(); 

对,就是这么easy,Thread构造函数里的参数类型为ThreadStart,这个东西官方解释是一个委托(啊,这里就不讲委托了,好像是C#特有的吧?反正我理解就是一个函数指针类型的东西或者是说某函数的别名,至于如何关联方法与委托,就是用new 委托名(函数名)的方法),表示此线程开始执行时要调用的方法。

关于委托大家可以下载http://down.51cto.com/data/1155877这个PPT,第229页处有详细讲解,简单易懂。

如上所说,在监听线程里我会创建一个监听的socket,然后有连接的话,会返回一个新的Socket对象,看代码:

  1. //用于连接通道的socket,我默认创建了5个,也就是说与Server端最多只能连通5个socket   
  2. Socket[] CommunicationSocket = new Socket[5];   
  3. //index来维护所创建的socket数组   
  4. int index = 0;   
  5. …省略…   
  6. //如有Client进行连接,返回一个新的socket   
  7. CommunicationSocket[index] = ListenSocket.Accept(); 

接下来就是本篇的关键部分了,由于我已经创建好了一个用于通信的CommunicationSocket,所以现在需要去创建一个独立的线程,用于专门为这个新的Socket作通信使用,而我传入的参数就是CommunicationSocket这个对象以及这个对象在socket数组中的位置index。
 

既然new ThreadStart()只能传入一个方法名,而没有给我们传参数的地方,那么针对于这个情况,我们需要用点小技巧,那就是使用类,看代码:

  1. //消息操作类,用于传入线程   
  2. public class MessageHandler   
  3. {   
  4.      Socket socket = null;   
  5.      int index = 0;   
  6.      bool StopFlag = false;   
  7.      public MessageHandler(Socket socket, int index)   
  8.      {   
  9.         this.socket = socket;   
  10.         this.index = index;   
  11.         Console.WriteLine("线程" + this.index + "号被创建!");   
  12.      }   
  13.      //接收线程调用的函数   
  14.      public void ReceiveMessage()   
  15.     {   
  16.         byte[] buffer = newbyte[1024*4];   
  17.         string message = null;   
  18.         try 
  19.         {   
  20.             while (!StopFlag)   
  21.             {   
  22.                 int result = this.socket.Receive(buffer, 0, buffer.Length, SocketFlags.None);   
  23.                 if (result < 0)   
  24.                 {   
  25.                     break;   
  26.                 }   
  27.                 message = System.Text.Encoding.UTF8.GetString(buffer);   
  28.                 Console.Write("Client(" + DateTime.Now.ToShortTimeString() + "):" + message.Trim());   
  29.                 Console.WriteLine();         
  30.             }   
  31.          }   
  32.           catch (System.Exception ex)   
  33.           {   
  34.               Console.WriteLine(ex.ToString());this.socket.Close();   
  35.           }   
  36.     }   
  37.     //发送线程调用的函数   
  38.     public void SendMessage()   
  39.     {   
  40.         byte[] buffer = newbyte[1024 * 4];   
  41.         string message = null;   
  42.         try 
  43.         {   
  44.             while (!StopFlag)   
  45.             {   
  46.                 message = Console.ReadLine();   
  47.                 if (message.ToLower().Equals("byebye"))   
  48.                 {   
  49.                     StopFlag = true;   
  50.                 }   
  51.                 buffer = System.Text.Encoding.UTF8.GetBytes(message);   
  52.                 this.socket.Send(buffer);         
  53.              }   
  54.          }   
  55.          catch (System.Exception ex)   
  56.          {                        
  57.             Console.WriteLine(ex.ToString());this.socket.Close();   
  58.          }   
  59.     }   

这是我自己定义的消息操作类,大家看看,这个类的里面即实现了利用socket发送消息,也实现了接收消息的方法。写到这大家有没有来点灵感呢?再继续往下看:

  1. //如果出现新的socket通道,那么分别创建一个该通道的接收线程与发送线程   
  2. //创建 MessageHandler类的对象,同时将参数传入到该对象中去,该实例的方法用于作为线程的目标方法   
  3. MessageHandler MsgHandler = new MessageHandler(CommunicationSocket[index], index);   
  4. ReceiveThread[index] = new Thread(new ThreadStart(MsgHandler.ReceiveMessage));   
  5. ReceiveThread[index].Start();   
  6. SendThread[index] = new Thread(new ThreadStart(MsgHandler.SendMessage));   
  7. SendThread[index].Start();   
  8. index++; 

这样就实现了往线程里传递1个以上的参数了。

这里主要就是展示一下如何去传多个参数,对于多线程的管理等细节上还是有很多漏洞的,所以大家挑干的来就好了。

另外我附上原码,跟文章中的有点出路,主要是在文章中我对一些变量名称稍加进行了修改,便于大家看代码。

***要说的是在C#多线程中传递一个参数的时候,有另外的专门方法,记得也是跟委托有关,不过具体我只是当时看了一下,这会儿已经记不得了,感兴趣的朋友可以去搜一下,不过话说回来,既然都会传多个参数了,传一个参数的话应该也很好搞定的。[[112899]][[112899]][[112899]]

希望能帮到有需要的人。

博客链接:http://zhouhongyu1989.blog.51cto.com/2931598/1410687

责任编辑:林师授 来源: 51cto博客
相关推荐

2009-08-28 15:57:56

C#线程传递参数

2009-08-27 17:47:18

C#匿名方法作为参数传

2009-09-07 03:23:40

C# Main方法

2024-02-27 10:44:58

C#线程后端

2024-10-18 16:58:26

2021-06-10 00:13:43

C#队列数据

2021-03-26 05:54:00

C#数据方法

2024-05-21 11:09:17

2024-10-14 16:25:59

C#线程锁代码

2009-08-12 18:04:44

编写C#多线程

2010-07-17 00:50:12

batch Telne

2024-05-10 07:44:23

C#进程程序

2024-10-21 16:59:37

C#编程多线程

2009-08-12 16:37:22

C#变量类型转换

2009-08-26 18:13:55

C#多线程lock

2011-04-25 14:42:10

C#lock

2024-04-23 09:35:27

线程终止C#多线程编程

2024-06-11 00:00:30

C#编程线程

2009-08-28 16:43:57

C#多线程学习

2009-09-04 15:09:48

C#多线程启动Squa
点赞
收藏

51CTO技术栈公众号