首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C# Ping-Class -如果连接错误,则取消Ping.Send()

C# Ping-Class -如果连接错误,则取消Ping.Send()
EN

Stack Overflow用户
提问于 2018-06-07 16:40:37
回答 1查看 357关注 0票数 -1

我构建了一个简单的程序,它接受一个包含一组服务器主机名的excel列表,并many其中的每一个,在控制台中返回有多少主机在线的结果。

我使用try/catch块来防止应用程序在主机名未知时崩溃(在连接错误时)。

现在我正在寻找一种解决方案,以便在连接错误时跳过ping请求,这样程序就可以继续ping队列中的下一个主机名,并且程序可以更快地完成,而无需等待异常发生。

这就是我现在使用的代码。

foreach (var server in serverList)
{        
     try
     {
         var reply = pingSender.Send(server, 1000);              

         //if server is reachable
         if (reply.Status == IPStatus.Success)
         {
             //add server to new excel and display it as online
             onlineList.Cells[serverCount, 1] = server + " is online";
             //increase counters
             serverCount++;
             onlineCount++;
         }
         else
         {
             //add server to new excel and display it as offline
             onlineList.Cells[serverCount, 2] = server + " is offline or unreachable.";                        
             serverCount++;
         } 
     }
     catch (Exception)
     {
         //if in any case the destination is unknown and prevent application from crashing
         onlineList.Cells[serverCount, 2] = server + " is offline or unreachable.";
         serverCount++;             
     }       
 }
EN

回答 1

Stack Overflow用户

发布于 2018-06-09 06:24:53

问题在于,您需要一个接一个地按顺序执行ping。通过让多个线程并行运行来执行pinging操作来提高性能,如此示例代码所示。

private async void button1_Click(object sender, EventArgs e)
{
    // Make a list of host names to ping
    List<string> hostnames = new List<string>();

    // Use local hostnames a .. z. 
    // and domain names a.com .. z.com
    for(char c = 'a'; c <= 'z'; c++)
    {
        hostnames.Add(c.ToString());
        hostnames.Add("www." + c + ".com");
    }

    // Use some well known hostnames
    hostnames.Add("www.google.com");
    hostnames.Add("www.microsoft.com");
    hostnames.Add("www.apple.com");

    // Ping the hostnames and get the results as a dictionary
    IReadOnlyDictionary<string, bool> results = await Task.Run(() => PingHosts(hostnames));

    // Output the content of the results, note that the order 
    // is not the same as in the original list of
    // hostnames because of parallel processing
    foreach(var result in results)
    {
        if(result.Value)
        {
            textBox1.AppendText("Ping to " + result.Key + ": OK" + Environment.NewLine);
        }
        else
        {
            textBox1.AppendText("Ping to " + result.Key + ": ERROR" + Environment.NewLine);
        }
    }
}

// This function will ping a single host and return true or false
// based on whether it can be pinged
private bool PingSingleHost(string hostname)
{
    try
    {
        Ping ping = new Ping();
        var reply = ping.Send(hostname, 1000);
        bool wasSuccessful = reply.Status == IPStatus.Success;
        return wasSuccessful;
    }
    catch(Exception)
    {
        return false;
    }
}

// Ping the given list of hostnames and return their status
// (can they be pinged) as a dictionary where the Key is the hostname
// and the value is a boolean with the ping result
private IReadOnlyDictionary<string, bool> PingHosts(IEnumerable<string> hostnames)
{
    // Use 30 parallel worker threads
    // This number can be quite high because the
    // workers will spend most time waiting 
    // for an answer
    int numberOfWorkers = 30;

    // Place the hosts into a queue
    ConcurrentQueue<string> jobsQueue = new ConcurrentQueue<string>(hostnames);

    // Use a concurrent dictionary to store the results
    // The concurrent dictionary will automatically handle
    // multiple threads accessing the dictionary at the same time
    ConcurrentDictionary<string, bool> results = new ConcurrentDictionary<string, bool>();

    // Worker function which keeps reading new hostnames from the given jobsQueue
    // and pings those hostnames and writes the result to the given results dictionary
    // until the queue is empty
    ThreadStart Worker = () =>
    {
        string hostname;

        // While the job queue is not empty, get a host from the queue
        while(jobsQueue.TryDequeue(out hostname))
        {
            // Ping the host and 
            bool wasSuccessful = PingSingleHost(hostname);

            // write the result to results dictionary
            results.TryAdd(hostname, wasSuccessful);
        }
    };


    // Start the Worker threads
    List<Thread> workers = new List<Thread>();

    for(int i = 0; i < numberOfWorkers; i++)
    {
        Thread thread = new Thread(Worker);
        thread.Start();
        workers.Add(thread);
    }

    // Wait for all workers to have finished
    foreach(var thread in workers)
    {
        thread.Join();
    }

    return results;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50736691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档