背景工人平

时间:2014-03-10 21:01:03

标签: c# .net backgroundworker ping

  • 问题:对离线设备进行Ping操作需要10-15秒。

  • 目标:如果ping或后台工作者运行时间超过5秒,我想结束/终止/停止或后台工作人员需要什么。 我有什么建议吗?

目前,当我ping一台在线设备时,它会在第一秒内回复。

private void backgroundWorkerPing_DoWork(object sender, DoWorkEventArgs e)
{
    string pcName = e.Argument.ToString();

    lblIPAddress.Invoke((Action)(() => lblIPAddress.ForeColor = Color.Black));

    lblStatus.GetCurrentParent().Invoke((Action)(() => lblStatus.Text = String.Format("Pinging {0}", pcName)));                

    string ipAddress = GetSinglePing(pcName);                       
    e.Result = ipAddress;
}

private string GetSinglePing(string pcName)
{
    Network net = new Network();
    return net.Pinger(pcName);
}

public class Network
{
    //My Ping Method
    public string Pinger(string pcName, int bufferSize = 32)
    {
        Ping ping = new Ping();
        byte[] buffer = new byte[bufferSize];
        PingOptions pingOpt = new PingOptions(64, true);            

        try
        {
            PingReply pingReply = ping.Send(pcName, 100, buffer, pingOpt);

            if (pingReply.Status == IPStatus.Success)
            {
                return pingReply.Address.ToString();
            }
            else
            {
                return "Offline";
            }
        }
        catch
        {
            return "Offline";
        }
    }            
}

2 个答案:

答案 0 :(得分:1)

再次修改:

如我之前的“编辑”中所述,您已经在代码中设置了ping超时。所以你真的不应该为你的手术延迟5到15秒。也许问题出在其他地方?

例如,使用以下代码(简单的控制台应用程序),它迭代IP列表,然后以IP - STATE - TIME USED

的格式显示每个的ping结果
public class Program
{
    private static void Main(string[] args)
    {
        var p = new Program();
        p.PingPong();
        Console.ReadLine();
    }

    private void PingPong()
    {
         var ips = new List<string>()
            {
                "43.128.240.28",
                "159.203.123.166",
                ... 30 in total in this test ...
                "201.131.43.87",
                "108.232.183.145"
            };

        foreach (var ip in ips)
        {
            string ip1 = ip;
            Task.Factory.StartNew(async () =>
                {
                    var newtwork = new Network();
                    var start = DateTime.Now;
                    string ping = newtwork.Pinger(ip1);
                    Console.WriteLine("{0} - {1} - {2}ms", ip, ping, (DateTime.Now - start).TotalMilliseconds);
                });
        }
    }
}

或多或少输出以下内容。

75.146.125.27 - Offline - 998.0982ms
190.37.198.208 - Offline - 978.329ms
90.82.250.179 - Offline - 975.3303ms
141.231.190.96 - Offline - 998.3851ms
38.89.231.171 - Offline - 976.3265ms
183.179.51.148 - Offline - 999.1762ms
125.238.115.199 - Offline - 977.1139ms
201.131.43.87 - Offline - 975.1229ms
154.165.188.89 - Offline - 978.1232ms
86.8.40.161 - Offline - 979.1236ms
108.232.183.145 - Offline - 998.6617ms

这些请求都没有超过一(1)秒,这是我自己设置的超时时间。

答案是: 将每个请求作为新任务启动并完全抛弃后台工作程序,将ping超时设置为您实际需要的级别,并在需要时使用 .BeginInvoke()将响应委托回UI线程(而不是Invoke())。

希望这可以帮助你前进!

修改

好的,所以我看到你已经将timeout设置为100毫秒,所以不应该花很长时间。但是你会做以下事情:

PingReply pingReply;
do
{
    pingReply = ping.Send(pcName, 100, buffer, pingOpt);                    
}
while(pingReply.Status != IPStatus.Success);
return pingReply.Address.ToString();    

它会帮助你摆脱那里的循环吗?


也许您可以将所有ping作为单独的任务启动,只要让它们存在,只要需要它们?

Task.Factory.StartNew(() => Pinger("pcName"));

答案 1 :(得分:0)

using System.Net.NetworkInformation;

Ping pingSender = new Ping ();
        PingOptions options = new PingOptions ();
        options.DontFragment = true;
        string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        byte[] buffer = Encoding.ASCII.GetBytes (data);
        int timeout = 1000; //to timeout after 1s
        PingReply reply = pingSender.Send (args[0], timeout, buffer, options);
        if (reply.Status == IPStatus.Success)
        {
            Console.WriteLine ("Address: {0}", reply.Address.ToString ());
            Console.WriteLine ("RoundTrip time: {0}", reply.RoundtripTime);
            Console.WriteLine ("Time to live: {0}", reply.Options.Ttl);
            Console.WriteLine ("Don't fragment: {0}", reply.Options.DontFragment);
            Console.WriteLine ("Buffer size: {0}", reply.Buffer.Length);
        }

http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping(v=vs.110).aspx

中的更多示例