Large amount of pings in async task - getting Exce

2019-07-20 17:28发布

问题:

I posted a previous question about this, I found a sort of working method using threads - but it was causing reliability issues when variables were rewritten between threads. I was pointed towards using ping async and tasks, but I'm getting the following exception:

Error: System.InvalidOperationException: An asynchronous call is already in progress. It must be completed or canceled before you can call this method.

That points specifically to the "await PingAsync(HostList)" and "await Task.WhenAll(tasks)"

Heres the code:

            MySqlConnection Connection = new MySqlConnection(ConnectionString);
            Connection.Open();
            MySqlCommand query = Connection.CreateCommand();
            query.CommandText = "SELECT obj_id AS id,ip FROM objects LIMIT 15";
            MySqlDataReader Nodes = query.ExecuteReader();

            // Record in log that a NEW iteration is starting - for tracking issues with pings
            Library.WriteErrorLog("######################## New Iteration ########################");

            var HostList = new List<HostObject>();

            int i = 1;
            while (Nodes.Read())
            {
                var Host = new HostObject();
                Host.HostName = Nodes["ip"].ToString();
                Host.HostID = Nodes["id"].ToString();
                HostList.Add(Host);
                i++;
            }

            Connection.Close();

            var results = await PingAsync(HostList);
            bool WaitingOnPings = false;
            while (WaitingOnPings == false)
            {
                if (results != null)
                {
                    foreach (PingReply result in results)
                    {
                        Library.WriteErrorLog(result.Status.ToString());
                    }

                    WaitingOnPings = true;
                }
                else
                {
                    Thread.Sleep(500);
                }
            }

and :

private async Task<List<PingReply>> PingAsync(List<HostObject> HostList)
    {
        Ping pingSender = new Ping();
        var tasks = HostList.Select(HostName => pingSender.SendPingAsync(HostName.ToString(), 2000));
        var results = await Task.WhenAll(tasks);

        return results.ToList();
    }

Thanks for the help!

回答1:

Ping was probably not intended to be used for multiple concurrent requests. Try creating a new Ping object for each host.

private async Task<List<PingReply>> PingAsync(List<HostObject> HostList)
{
    var tasks = HostList.Select(HostName => new Ping().SendPingAsync(HostName.ToString(), 2000));
    var results = await Task.WhenAll(tasks);

    return results.ToList();
}