新人关于线程池相关的疑问(WaitHandle.WaitAll和ThreadPool.QueueUserWorkItem)
wmsdg 2008-07-30 02:55:21 程序代码如下文,都是可以执行并符合要求的(输入主机ip,起始和结束端口,启用线程池逐端口测试tcp连接,待全部线程空闲后,主线程继续并结束)
问题1:ascan.eventX = eventXAll[i - startPort];//这里传递的是对象的地址是么?
ascan.eventX和 eventXAll[i - startPort]指向的是内存的同一地址?
问题2:WaitHandle.WaitAll方法似乎最多只能控制64个线程,怎么办?
问题3:为什么ThreadPool.QueueUserWorkItem(myWaitCB,remote);也可以用ThreadPool.QueueUserWorkItem(ascan.ScanPortWork,remote);代替
using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;
public class PortScan
{
public static void Main()
{
Console.WriteLine("输入主机名称: ");
string hostName = Console.ReadLine();
IPAddress ip = IPAddress.Parse(hostName);
Console.WriteLine("输入开始扫描通信端口: ");
int startPort = int.Parse(Console.ReadLine());
Console.WriteLine("输入结束扫描通信端口: ");
int endPort = int.Parse(Console.ReadLine());
ThreadPool.SetMaxThreads(100,300);
ManualResetEvent[] eventXAll = new ManualResetEvent[(endPort-startPort+1)];//设置一个ManualResetEvent类的数组,数量为所要开启的进程数
for (int i = startPort; i <= endPort; i++)
{
IPEndPoint remote=new IPEndPoint (ip,i);
ScanPort ascan = new ScanPort();
eventXAll[i - startPort] = new ManualResetEvent(false);//初始化一个ManualResetEvent对象
ascan.eventX = eventXAll[i - startPort];//把其传递给子线程?
WaitCallback myWaitCB=new WaitCallback (ascan.ScanPortWork);
ThreadPool.QueueUserWorkItem(myWaitCB,remote);
}
//eventX.WaitOne(Timeout.Infinite, true);
WaitHandle.WaitAll(eventXAll);//等待ManualResetEvent数组中所有元素均为有效
Console.WriteLine("指定通信端口扫描完成!! ");
Console.WriteLine("请按[Enter] 离开!! ");
Console.ReadLine();
}
}
public class ScanPort
{
public ManualResetEvent eventX;//设置ManualResetEvent对象,来接收主线程传递的ManualResetEvent对象
public void ScanPortWork(object remote)
{
TcpClient myTcpClient = new TcpClient();
IPEndPoint rm = (IPEndPoint)remote;
int port = 0;
try
{
myTcpClient.Connect(rm);
Console.WriteLine("Port " + rm.Port.ToString() + " 目前打开!!");
port = rm.Port;
}
catch (SocketException)
{
Console.WriteLine("Port " + rm.Port.ToString() + "关闭!");
}
finally
{
myTcpClient.Close();
}
eventX.Set(); //设置为有效
}
}