【问题标题】:C# how to process a listC#如何处理列表
【发布时间】:2014-03-14 08:37:58
【问题描述】:

以下是我尝试创建的用于重新启动应用程序的程序的代码。我尝试了几种不同的方法来使其工作,研究了 Google 和 Stackoverflow 关于“列表”的信息,但我要么不理解,要么没有得到我需要的东西。 “RestartData”是一个存储属性的 .cs 文件,program.cs 是程序的唯一其他部分。这是主要部分。

我遇到的问题在于 processRestartList 函数。我想浏览列表(foreach)并检查 LastRestartTime 是什么,如果它大于 RestartInterval,则终止进程并重新启动它。我的问题是不确定如何实际编写语法以使函数 processRestartList 真正做到这一点。任何和所有的帮助将不胜感激。

class RestartData
    {
        public string ProgramLocation { get; set; }
        public bool Active { get; set; }
        public int RestarInterval { get; set; }
        public bool RestartIfRunning { get; set; }
        public string ProgramServer { get; set; }
        public string ProcessName { get; set; }
        public DateTime LastRestartTime { get; set; }
    }

 namespace ApplicationWatcher
    {
        public class RestartApplicationTask
        {
            public Int32 SleepInterval { get; set; }
            public String Status { get; set; }
            public String Error { get; set; }
            public bool Stopping { get; set; }
            public static log4net.ILog log { get; set; }

        public void Start()
        {
            Stopping = false;
            Error = "";
            Status = "Starting";
            if (SleepInterval == 0)
            {
                SleepInterval = 3600;
            }

            //make sure there is a logger
            if (log == null)
            {
                log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigurationManager.AppSettings["log4net"])));

                log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            }


            //This calls a method within the class. The name of the class is not needed, but the list and name of list is needed.
            List<RestartData> restartWorkList = AppRestartList();

            try
            {
                processRestartList(restartWorkList);
            }
            catch (Exception e)
            {
                //Replace with logging
                log.Info("Error: could not process " + restartWorkList);
            }
        }

        public static Happy.Common.HappyTools.DB GetCurrentlyRunningApplications(bool Active)
        {

        String qry= "SELECT ProgramLocation, Active, RestartIfRunning FROM any_database.dbo.AppWatcher WITH (NOLOCK) WHERE Active = 1";
        //qry = qry.Replace("<Active>", Active.ToString());
        SqlCommand cmd = new SqlCommand(qry, (SqlConnection)DB.MakeConnection("any_database"));
        DataTable dt;

        Happy.Common.HappyTools.DB returnValue = new Happy.Common.HappyTools.DB();
        try
        {
            dt = DB.ExecuteTable(cmd, "any_database");

            DataRow thisRow = dt.Rows[0];
        }
        catch (Exception e)
        {
            //do something
        }
        finally { }
        return returnValue;
        }

        static List<RestartData> AppRestartList()
        {
            List<RestartData> restartDatas = new List<RestartData>();

            //Don't need to create a new instance but does need to be assigned to at least null
            RestartData restartData = null;

            //This is an actual SQL Query that would be the same as in a SQL manager.
            string sqlQuery = "Select RestartTime, ProgramLocation, LastRestartTime, RestartInterval, ProgramServer, RestartIfRunning, ProcessName from dbo.AppWatcher where active=1;";

            //execute sql query
            //execute database reader
            SqlCommand command = new SqlCommand(sqlQuery, (SqlConnection)DB.MakeConnection("any_database"));
            DataTable dt;  



            command.Connection.Open();

            dt = DB.ExecuteTable(command, "any_database");

            foreach (DataRow row in dt.Rows)
            {
                //move stuff from reader into log data, and exp
                //not RestartData restartData = new RestartData();  The RestartData() method is already declared
                restartData = new RestartData();
                restartData.ProgramLocation = Misc.NullSafeString(row["programLocation"]);
                //restartData.Active = Misc.NullSafeBool(row["active"]);
                restartData.RestarInterval = Misc.NullSafeInt(row["restartInterval"]);
                restartData.RestartIfRunning = Misc.NullSafeBool(row["restartIfRunning"]);
                restartData.ProcessName = Misc.NullSafeString(row["processName"]);
                restartData.LastRestartTime = Misc.NullSafeDateTime(row["lastRestartTime"]);

                //add restartData to list
                restartDatas.Add(restartData);

            }
            return restartDatas;
        }

        static void processRestartList(List<RestartData>restartJob)
        {    


            //i represents all the properties in LogData
            **foreach(RestartData i in restartJob)
            {
                if (i <= RestartData())
                {
                    i.LastRestartTime.AddHours(-1);
                }

            }**
         }     
    }
}

【问题讨论】:

  • 我只想遍历列表并检查 LastRestartTime 是否大于设置的值
  • 最好将RestartInterval 设为TimeSpan。您可以执行TimeSpan.FromSeconds(someNumber) 之类的操作来轻松创建特定单位的时间间隔。

标签: c# list function


【解决方案1】:

RestarInterval 的单位不清楚,所以我假设seconds。如果它有所不同,请相应地更改TotalSeconds(TotalMinutes、TotalHours 等)。

foreach(var data in restartJob.Where(x=> DateTime.Now.Subtract(x.LastRestartTime).TotalSeconds > x.RestarInterval))
{
    //kill
}

【讨论】:

  • 在 foreach 循环中有DateTime.Now,您需要注意一些副作用。当您处理项目时,您将要比较的时间将“与您一起移动”,对于这样的快速循环可能并不重要,但如果这用于可能需要很长时间来处理的循环,具体取决于您的行为希望您可能希望将其移出循环到var now = DateTime.Now 并在循环内使用now.Subtract.(...。 (这更针对未来的读者,而不是答案的海报)
【解决方案2】:

你想要类似下面的东西。假设RestartInterval 代表小时。

// Check what LastRestartTime is and if it is greater that RestartInterval, kill the process and restart it.
DateTime dt = DateTime.Now; // Keep DateTime static.
foreach(RestartData restartData in restartJob)
{
    if (dt >= restartData.LastRestartTime.AddHours(restartData.RestarInterval))
    {
        restartData.LastRestartTime = dt;
        // restart process
    }
}

【讨论】:

  • 请参阅my comment to L.B's answer,了解实施者在循环中使用DateTime.Now 时应注意的事项。
  • 谢谢,这让我走上了正确的道路。我只是不知道如何让它发挥作用。
  • 我把减号去掉了,因为我把我的逻辑搞混了。 @ScottChamberlain,已编辑。
猜你喜欢
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
  • 2021-02-03
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多