如何提高下面代码的性能?

时间:2015-08-17 06:06:46

标签: c# performance networking ping

我编写了一个代码来ping网络中的300个系统,并将状态(离线/在线)更新到Access数据库文件中。

我正在使用任务类。 Ping 300系统只需不到一秒钟,但将这些状态插入数据库文件需要将近30到40秒。

它降低了我的应用程序的性能,请查看我的代码。如果

主要方法

private static void Main(string[] args)
    {
        #region Reading IpAdddress

        List<string> address = new List<string>();
        Task t = Task.Run(() =>
        {
            var reader = new StreamReader(File.OpenRead(Environment.CurrentDirectory + @"\address.csv"));
            while (!reader.EndOfStream)
            {
                var lines = reader.ReadLine();
                var values = lines.Split(';');
                address.Add(values[0]);
            }
        });

        #endregion

        Stopwatch timeSpan = Stopwatch.StartNew();

        t.Wait();


        AsyncPingTask(address).Wait();
        Console.WriteLine("Update Completed");

        Console.WriteLine(timeSpan.ElapsedMilliseconds);
        Console.ReadLine();
    }

Ping任务

 private static async Task AsyncPingTask(List<string> ipaddress)
    {
        try
        {
            Console.WriteLine("Ping Started");                              

            var pingTasks = ipaddress.Select(ip =>
            {
                return new Ping().SendTaskAsync(ip);                    
            }).ToList();

           var replies= await Task.WhenAll(pingTasks);
            Console.WriteLine("Ping Completed");

            int online, offline;
            online = 0;
            offline = 0;
            Console.WriteLine("Update in progress...");                

            foreach (var pingReply in replies)
            {
                var status = "";
                if (pingReply.Reply.Status.ToString() == "Success")
                {
                    online++;
                    status = "Online";

                }
                else
                {
                    status = "Offline";
                    offline++;
                }
                Program p = new Program();                    
                Parallel.Invoke(() =>
                {
                    p.UpdateSystemStatus(pingReply.Address, status);
                });

            }


            Console.WriteLine("Online Systems : {0}", online);
            Console.WriteLine("Offline Systems : {0}", offline);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            throw;
        }

    }

更新状态方法

private void UpdateSystemStatus(string ipAddr, string status)
{
   using (OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\/Topology.accdb"))
   {
      string query = "UPDATE SystemStatus SET SystemStatus=@SystemStatus WHERE IP='" + ipAddr + "'";

      OleDbCommand cmd = new OleDbCommand(query, con);
      con.Open();
      cmd.Parameters.AddWithValue("@SystemStatus", status);

      cmd.ExecuteNonQuery();         
   }
}

1 个答案:

答案 0 :(得分:1)

这不是我的专业领域,但我的猜测是,为每个更新的记录创建新的OleDbConnection会产生很多开销。我可以想象它至少必须在文件系统中打开访问数据库,检查权限,解析一堆东西等等......一旦创建连接的方法可能会更好。我还看到有一些可能会提高性能的事务机制。

using (OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\/Topology.accdb"))
{
    con.Open();
    var trans = con.BeginTransaction();

    foreach (var pingReply in replies)
    {
        var status = "";
        if (pingReply.Reply.Status.ToString() == "Success")
        {
            online++;
            status = "Online";
        }
        else
        {
            status = "Offline";
            offline++;
        }

        string query = "UPDATE SystemStatus SET SystemStatus=@SystemStatus WHERE IP='" + ipAddr + "'";

        OleDbCommand cmd = new OleDbCommand(query, con);
        cmd.Transaction = trans;
        cmd.Parameters.AddWithValue("@SystemStatus", status);

        cmd.ExecuteNonQuery();         
    }
    trans.Commit();
}