当前位置: 首页 > 科技观察

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

时间:2023-03-13 18:59:29 科技观察

有些情况下,我们在启动一个线程的时候,会向该线程传递参数。有时候除了功能上的需要,我觉得还有就是让我们管理启动的线程组(当然如果只开一两个线程不好管理,我说的线程组指的是10个+线程,我们很难主动控制)。因为刚刚接触C#,所以并没有使用过多的线程来实现C#下的一些功能。通过学习,我发现简单的启动线程很容易,但是给线程传递一些参数就变得有点啰嗦了。这里我想说的是传入参数个数>=2。但是,让我们一步步来,带您了解如何在C#下进行多线程处理。上一篇文章中提到的网络通信的例子走完了整个过程。这里的网络通信只是举例说明,仍然是在控制台(Console)程序下实现的。当Server端想要能够与多个Client通信时,就必须使用多线程机制。我的想法:在程序启动的时候,Server端开一个专门的线程进行监听,这样如果主程序想做其他事情就不会耽误时间。当监听线程检测到有连接请求时,它会创建一个新的Socket(我们暂且称之为SASocket)来与这个IP服务器通信。当然,这个SA通信的内容(比如:发送和接收消息)是在新的一两个线程(我们暂且称之为TA线程)中实现的。这时候我们需要将SA的独占ID传入TA线程,让TA线程只为SA服务。之后依次推导。下面创建监听线程,这也是C#下最简单的多线程使用——创建多线程ThreadListenThread=newThread(newThreadStart(ServerListener));ListenThread.Start();是的,就是这么简单,Thread构造函数中的参数类型就是ThreadStart。官方对这个东西的解释是delegate(啊,这里就不说delegates了,好像是C#特有的吧?反正我是理解为函数指针类型或者某个函数的别名。如对于如何关联methods和delegate,即使用newdelegatename(函数名method),意思是这个线程开始执行时要调用的方法。关于委托,可以下载PPThttp://down.51cto.com/data/1155877。229页有详细解释,通俗易懂。上面说过,在监听线程中,我会创建一个监听socket,如果有连接,就会返回一个新的Socket对象,看代码://用于连接通道的socket,我默认创建了5个,也就是说Server端最多只能有5个socket连接Socket[]CommunicationSocket=newSocket[5];//index维护创建的socket数组intindex=0;...省略...//如果有Client要连接,则返回一个新的socketCommunicationSocket[index]=ListenSocket.Accept();接下来是本文的重点部分,由于我已经创建了一个CommunicationSocket用于通信,所以现在我需要创建一个独立的线程来为这个新的Socket进行通信,我传入的参数是CommunicationSocket对象和此对象在套接字数组中的位置索引。既然newThreadStart()只能传入一个方法名,没有地方给我们传递参数,那么对于这种情况,我们需要用一个小技巧,那就是使用类,看代码://消息操作类,使用IncomingthreadpublicclassMessageHandler{Socketsocket=null;intindex=0;boolStopFlag=假;publicMessageHandler(Socketsocket,intindex){this.socket=socket;this.index=索引;Console.WriteLine("线程"+this.index+"创建数量!");}//接收线程调用的函数publicvoidReceiveMessage(){byte[]buffer=newbyte[1024*4];字符串消息=空;尝试{while(!StopFlag){intresult=this.socket.Receive(buffer,0,buffer.Length,SocketFlags.None);如果(结果<0){中断;}message=System.Text.Encoding.UTF8.GetString(缓冲区);Console.Write("Client("+DateTime.Now.ToShortTimeString()+"):"+message.Trim());控制台.WriteLine();}}catch(System.Exceptionex){Console.WriteLine(ex.ToString());this.socket.Close();}}//发送线程调用的函数publicvoidSendMessage(){byte[]buffer=newbyte[1024*4];字符串消息=空;尝试{while(!StopFlag){message=Console.ReadLine();如果(消息。ToLower()。等于s("byebye")){StopFlag=true;}buffer=System.Text.Encoding.UTF8.GetBytes(消息);this.socket.Send(缓冲区);}}catch(System.Exceptionex){Console.WriteLine(ex.ToString());this.socket.Close();}}}这是我自己定义的一个消息操作类。来看看,这个类不仅实现了使用socket发送消息,还实现了消息的接收。这个怎么写,有没有启发呢?继续往下看://如果出现新的socket通道,则分别为该通道创建一个接收线程和一个发送线程//创建一个MessageHandler类的对象,同时向该对象传入参数,方法实例的目标方法用作线程MessageHandlerMsgHandler=newMessageHandler(CommunicationSocket[index],index);ReceiveThread[index]=newThread(newThreadStart(MsgHandler.ReceiveMessage));ReceiveThread[index].Start();SendThread[index]=newThread(newThreadStart(MsgHandler.SendMessage));SendThread[index].Start();索引++;这样一来,可以向线程传递多个参数。这里的主要目的是展示如何传递多个参数。多线程管理的细节上还有很多漏洞,大家可以自己选择。另外附上原代码,有点出文章的地方,主要是对文章中的一些变量名稍作修改,方便大家阅读代码。***我想说的是,在C#多线程中传递参数的时候,还有一个比较特殊的方法,我记得也是和委托相关的,但是当时只是看了,不会现在记起来了,有兴趣的朋友可以搜索一下,不过话又说回来了,既然传了多个参数,那么用一个参数应该很容易搞定。希望能帮助到有需要的人。博客链接:http://zhouhongyu1989.blog.51cto.com/2931598/1410687