Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异步Ping:如何避免内存不足异常?_C#_.net_Asynchronous_Ping - Fatal编程技术网

C# 异步Ping:如何避免内存不足异常?

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

问题:我想在子网中搜索所有计算机。 因此,我向子网中的所有IP地址发送ping

问题是,如果我只扫描192.168.0,它就可以正常工作。”。 但是如果我扫描192.168..*,那么我会得到一个“内存不足”异常

为什么??我是否必须限制线程,或者新ping占用的内存在完成后不会被破坏,或者我是否需要调用gc.collect()

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实例的列表,并跟踪它们何时运行