C# 异步Ping:如何避免内存不足异常?
问题:我想在子网中搜索所有计算机。 因此,我向子网中的所有IP地址发送ping 问题是,如果我只扫描192.168.0,它就可以正常工作。”。 但是如果我扫描192.168..*,那么我会得到一个“内存不足”异常 为什么??我是否必须限制线程,或者新ping占用的内存在完成后不会被破坏,或者我是否需要调用gc.collect()C# 异步Ping:如何避免内存不足异常?,c#,.net,asynchronous,ping,C#,.net,Asynchronous,Ping,问题:我想在子网中搜索所有计算机。 因此,我向子网中的所有IP地址发送ping 问题是,如果我只扫描192.168.0,它就可以正常工作。”。 但是如果我扫描192.168..*,那么我会得到一个“内存不足”异常 为什么??我是否必须限制线程,或者新ping占用的内存在完成后不会被破坏,或者我是否需要调用gc.collect() static void Main(字符串[]args) { 字符串strFromIP=“192.168.0.1”; 字符串strToIP=“192.168.255.2
static void Main(字符串[]args)
{
字符串strFromIP=“192.168.0.1”;
字符串strToIP=“192.168.255.255”;
Oyster.Math.IntX omiFromIP=0;
Oyster.Math.IntX ompitoip=0;
IsValidIP(strFromIP,参考omiFromIP);
IsValidIP(strToIP,参考省略);
对于(Oyster.Math.IntX ommithisip=omiFromIP;ommithisip我想问题是,您几乎同时生成了63K ping请求。如果没有进一步的内存分析,很难说哪些部分占用了内存。您使用的网络资源可能有限。限制活动pin的数量gs将简化本地资源和网络流量的使用
我会再次探讨,Parallel.For
construction与的结合应该会让您更容易理解
注意:对于.Net 3.5用户,.我想问题是您几乎同时生成了63K ping请求。如果没有进一步的内存分析,很难说哪些部分消耗内存。您使用的是网络资源,而这些资源可能是有限的。限制活动pin的数量gs将简化本地资源和网络流量的使用
我会再次探讨,Parallel.For
construction与的结合应该会让您更容易理解
注意:对于.Net 3.5用户,.首先:第一次仅启动1000次ping(在主循环中)
第二:将以下参数移动到程序类(成员变量)
第三:在AsyncPingCompleted中,在底部执行如下操作:
public void AsyncPingCompleted (bla bla bla)
{
//[..other code..]
lock (syncLock)
{
if (omiToIP < omiCurrentIp)
{
++omiCurrentIp;
System.Net.IPAddress sniIPaddress = System.Net.IPAddress.Parse(IPn2IPv4(omiCurrentIp));
SendPingAsync(sniIPaddress);
}
}
}
public void异步完成(bla bla bla)
{
//[…其他代码]
锁定(同步锁定)
{
if(省略ip
更新完整的代码示例
public class Example
{
// Number of pings that can be pending at the same time
private const int InitalRequests = 10000;
// variables from your Main method
private Oyster.Math.IntX _omiFromIP = 0;
private Oyster.Math.IntX _omiToIP = 0;
private Oyster.Math.IntX _omiCurrentIp = 0;
// synchronoize so that two threads
// cannot ping the same IP.
private object _syncLock = new object();
static void Main(string[] args)
{
string strFromIP = "192.168.0.1";
string strToIP = "192.168.255.255";
IsValidIP(strFromIP, ref _omiFromIP);
IsValidIP(strToIP, ref _omiToIP);
for (_omiCurrentIp = _omiFromIP; _omiCurrentIp <= _omiFromIP + InitalRequests; ++_omiCurrentIp)
{
Console.WriteLine(IPn2IPv4(_omiCurrentIp));
System.Net.IPAddress sniIPaddress = System.Net.IPAddress.Parse(IPn2IPv4(_omiCurrentIp));
SendPingAsync(sniIPaddress);
}
Console.WriteLine(" --- Press any key to continue --- ");
Console.ReadKey();
} // Main
// http://pberblog.com/post/2009/07/21/Multithreaded-ping-sweeping-in-VBnet.aspx
// http://www.cyberciti.biz/faq/how-can-ipv6-address-used-with-webbrowser/#comments
// http://www.kloth.net/services/iplocate.php
// http://bytes.com/topic/php/answers/829679-convert-ipv4-ipv6
// http://stackoverflow.com/questions/1434342/ping-class-sendasync-help
public void SendPingAsync(System.Net.IPAddress sniIPaddress)
{
int iTimeout = 5000;
System.Net.NetworkInformation.Ping myPing = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingOptions parmPing = new System.Net.NetworkInformation.PingOptions();
System.Threading.AutoResetEvent waiter = new System.Threading.AutoResetEvent(false);
myPing.PingCompleted += new System.Net.NetworkInformation.PingCompletedEventHandler(AsyncPingCompleted);
string data = "ABC";
byte[] dataBuffer = Encoding.ASCII.GetBytes(data);
parmPing.DontFragment = true;
parmPing.Ttl = 32;
myPing.SendAsync(sniIPaddress, iTimeout, dataBuffer, parmPing, waiter);
//waiter.WaitOne();
}
private void AsyncPingCompleted(Object sender, System.Net.NetworkInformation.PingCompletedEventArgs e)
{
System.Net.NetworkInformation.PingReply reply = e.Reply;
((System.Threading.AutoResetEvent)e.UserState).Set();
if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
{
Console.WriteLine("Address: {0}", reply.Address.ToString());
Console.WriteLine("Roundtrip time: {0}", reply.RoundtripTime);
}
// Keep starting those async pings until all ips have been invoked.
lock (_syncLock)
{
if (_omiToIP < _omiCurrentIp)
{
++_omiCurrentIp;
System.Net.IPAddress sniIPaddress = System.Net.IPAddress.Parse(IPn2IPv4(_omiCurrentIp));
SendPingAsync(sniIPaddress);
}
}
}
}
公共类示例
{
//可同时挂起的ping数
private const int InitalRequests=10000;
//主方法中的变量
private Oyster.Math.IntX_omiFromIP=0;
private Oyster.Math.IntX_ompitoip=0;
private Oyster.Math.IntX\u omiCurrentIp=0;
//同步使两个线程
//无法ping同一IP。
私有对象_syncLock=新对象();
静态void Main(字符串[]参数)
{
字符串strFromIP=“192.168.0.1”;
字符串strToIP=“192.168.255.255”;
IsValidIP(strFromIP,参考文献);
IsValidIP(strToIP,参考省略);
对于(_-omiCurrentIp=_-omiCurrentIp;_-omiCurrentIpFirst):第一次仅启动1000次ping(在主循环中)
第二:将以下参数移动到程序类(成员变量)
第三:在AsyncPingCompleted中,在底部执行如下操作:
public void AsyncPingCompleted (bla bla bla)
{
//[..other code..]
lock (syncLock)
{
if (omiToIP < omiCurrentIp)
{
++omiCurrentIp;
System.Net.IPAddress sniIPaddress = System.Net.IPAddress.Parse(IPn2IPv4(omiCurrentIp));
SendPingAsync(sniIPaddress);
}
}
}
public void异步完成(bla bla bla)
{
//[…其他代码]
锁定(同步锁定)
{
if(省略ip
更新完整的代码示例
public class Example
{
// Number of pings that can be pending at the same time
private const int InitalRequests = 10000;
// variables from your Main method
private Oyster.Math.IntX _omiFromIP = 0;
private Oyster.Math.IntX _omiToIP = 0;
private Oyster.Math.IntX _omiCurrentIp = 0;
// synchronoize so that two threads
// cannot ping the same IP.
private object _syncLock = new object();
static void Main(string[] args)
{
string strFromIP = "192.168.0.1";
string strToIP = "192.168.255.255";
IsValidIP(strFromIP, ref _omiFromIP);
IsValidIP(strToIP, ref _omiToIP);
for (_omiCurrentIp = _omiFromIP; _omiCurrentIp <= _omiFromIP + InitalRequests; ++_omiCurrentIp)
{
Console.WriteLine(IPn2IPv4(_omiCurrentIp));
System.Net.IPAddress sniIPaddress = System.Net.IPAddress.Parse(IPn2IPv4(_omiCurrentIp));
SendPingAsync(sniIPaddress);
}
Console.WriteLine(" --- Press any key to continue --- ");
Console.ReadKey();
} // Main
// http://pberblog.com/post/2009/07/21/Multithreaded-ping-sweeping-in-VBnet.aspx
// http://www.cyberciti.biz/faq/how-can-ipv6-address-used-with-webbrowser/#comments
// http://www.kloth.net/services/iplocate.php
// http://bytes.com/topic/php/answers/829679-convert-ipv4-ipv6
// http://stackoverflow.com/questions/1434342/ping-class-sendasync-help
public void SendPingAsync(System.Net.IPAddress sniIPaddress)
{
int iTimeout = 5000;
System.Net.NetworkInformation.Ping myPing = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingOptions parmPing = new System.Net.NetworkInformation.PingOptions();
System.Threading.AutoResetEvent waiter = new System.Threading.AutoResetEvent(false);
myPing.PingCompleted += new System.Net.NetworkInformation.PingCompletedEventHandler(AsyncPingCompleted);
string data = "ABC";
byte[] dataBuffer = Encoding.ASCII.GetBytes(data);
parmPing.DontFragment = true;
parmPing.Ttl = 32;
myPing.SendAsync(sniIPaddress, iTimeout, dataBuffer, parmPing, waiter);
//waiter.WaitOne();
}
private void AsyncPingCompleted(Object sender, System.Net.NetworkInformation.PingCompletedEventArgs e)
{
System.Net.NetworkInformation.PingReply reply = e.Reply;
((System.Threading.AutoResetEvent)e.UserState).Set();
if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
{
Console.WriteLine("Address: {0}", reply.Address.ToString());
Console.WriteLine("Roundtrip time: {0}", reply.RoundtripTime);
}
// Keep starting those async pings until all ips have been invoked.
lock (_syncLock)
{
if (_omiToIP < _omiCurrentIp)
{
++_omiCurrentIp;
System.Net.IPAddress sniIPaddress = System.Net.IPAddress.Parse(IPn2IPv4(_omiCurrentIp));
SendPingAsync(sniIPaddress);
}
}
}
}
公共类示例
{
//可同时挂起的ping数
private const int InitalRequests=10000;
//主方法中的变量
private Oyster.Math.IntX_omiFromIP=0;
private Oyster.Math.IntX_ompitoip=0;
private Oyster.Math.IntX\u omiCurrentIp=0;
//同步使两个线程
//无法ping同一IP。
私有对象_syncLock=新对象();
静态void Main(字符串[]参数)
{
字符串strFromIP=“192.168.0.1”;
字符串strToIP=“192.168.255.255”;
IsValidIP(strFromIP,参考文献);
IsValidIP(strToIP,参考省略);
对于(_omiCurrentIp=_omicfromip;_omiCurrentIp伪代码
do
if pings_running > 100 then
sleep 100ms.
else
start ping
endif
loop while morepings
伪码
do
if pings_running > 100 then
sleep 100ms.
else
start ping
endif
loop while morepings
根据,System.Net.NetworkInformation.Ping
似乎为每个异步请求分配一个线程,“Ping扫描B类网络会创建100个线程,并最终导致内存不足错误。”
该人员使用的解决方法是使用原始套接字编写自己的实现。当然,您不必在F#中这样做,但这样做有很多好处。根据,System.Net.NetworkInformation.Ping
似乎为每个异步请求分配一个线程,并且“ping扫描B类网络会创建100个线程,并最终导致内存不足错误。”
该人员使用的解决方法是使用原始套接字编写自己的实现。当然,您不必在F#中这样做,但这样做有很多好处。最后……根本不需要ping
我所需要做的就是使它在调试时线程安全。
将添加更改为:
void Add( string m )
{
Invoke(new MethodInvoker(
delegate
{
add.Items.Add(m);
}));
//add.Items.Add( m );
}
最后…根本不需要ping
我所需要做的就是使它在调试时线程安全。
将添加更改为:
void Add( string m )
{
Invoke(new MethodInvoker(
delegate
{
add.Items.Add(m);
}));
//add.Items.Add( m );
}
我做了类似的事情。我解决项目问题的方法是将ping实例转换为IDisposable:
(myPing as IDisposable).Dispose()
因此,获取一个异步运行(X.X.X.1/254)的254个ping实例的列表,并跟踪它们何时运行