我正在创建一个记录计算机进程的程序,然后从那个初始时间开始,每隔X分钟,另一个日志保存在一个文本文件中。我已经写了文本文件,一切都很顺利。我似乎无法让DateTime正常工作,或者我误解了它的用途。
DateTime firstTime = DateTime.Now;
Process[] processlist = Process.GetProcesses();
foreach (Process theprocess in processlist)
{
sw.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
sw.WriteLine(firstTime);
DateTime now = DateTime.Now.AddMinutes(1);
sw.WriteLine(now);
while (DateTime.Now == DateTime.Now)
{
DateTime nuw = DateTime.Now;
sw.WriteLine(nuw);
if (nuw == now)
{
sw.WriteLine("It worked");
}
}
我知道while循环是可怕的,但我只是看到有什么可行的。我认为导致这个问题的是DateTime.Now,不会每秒更新/更改,它在整个持续时间内保持不变。即使是控制台并无休止地写出来,它仍然是最初被称为的日期。
所以,是的,我知道该怎么办。
答案 0 :(得分:2)
您应该使用每X分钟触发一次的计时器来完成您的任务。你的while循环将锁定程序的UI并占用大量的CPU。
答案 1 :(得分:1)
==
上的比较DateTime
比较内部滴答。刻度是100 ns或一千万分之一秒,在一毫秒内有10,000个刻度。相反,windows运行的周期时间约为20ms。比较就像试图在大小相当的大海捞针中找到针。
使用(nuw >= now)
代替,比较完全匹配或现在之后。
答案 2 :(得分:1)
System.Threading.Timer类应该可以解决问题。您必须为System.Threading命名空间提供一个使用。
static public void ListProcesses(Object stateInfo)
{
Process[] processlist = Process.GetProcesses();
foreach (Process theprocess in processlist)
{
Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
}
static void Main(string[] args)
{
//create a callback to our worker method
TimerCallback callback = new TimerCallback(ListProcesses);
// create a one minute timer tick
Timer stateTimer = new Timer(callback, null, 0, 60000);
// loop here forever
while (true)
{
//sleep every second so we dont hog the cpu
Thread.Sleep(1000);
//add program control logic
//if we want to exit the program with anything other than closing the window
}
}
答案 3 :(得分:0)
你应该尝试像
这样的东西if(now.CompareTo(nuw) < 0)
答案 4 :(得分:0)
比较时间上的平等有点像试图在射箭中分裂箭头。准确一分钟就不太可能了。
我想你想要if (nuw >= now)
答案 5 :(得分:0)
从我的角度来看,你造成问题的最大问题是你的变量命名,除非我遗漏了一些东西 - 总是使用清晰的变量名,这样你的代码就会自然地读出来。
如上所示使用计时器肯定是解决问题的绝佳方法,但是我会继续并继续使用您编写的代码的主题,因为计时器答案的作者已经涵盖了一个很好。
我必须承认,对于“while(true)”循环也往往非常害羞,因为我宁愿通过Start()和Stop()方法以及_isRunning变量更加主动地控制停止应用程序 - _isRunning就是你的循环条件。为简单起见,我会坚持一段时间(真实)。
所以,稍微改写一下,你的循环看起来像这样:
DateTime timeOfNextOperation = DateTime.Now.AddMinutes(1);
Console.WriteLine(timeOfNextOperation);
while (true)
{
if (DateTime.Now >= timeOfNextOperation)
{
Console.WriteLine("Do Stuff Here");
timeOfNextOperation = DateTime.Now.AddMinutes(1);
}
Thread.Sleep(1000);
}
你绝对必须将某种收益(某种类型的睡眠)放入你的循环中,否则你将在紧密的循环中使用100%的cpu。即使是1分钟的睡眠也会产生很大的不同,但要想想你是否真的需要它才能快速旋转 - 在这种情况下,它肯定不会,你每分钟只旋转一次每一秒都足够了。
你的循环也没有重置它,以便通过设置下一个操作的时间来实现每分钟,上面的操作。请注意,在这个例子中,我在完成任务后设置它(在这种情况下,打印一行:)) - 这意味着它将在每次执行之间运行1分钟,而不是每分钟 - 即任务需要30秒,然后它将在1分钟,然后2分30秒发生。如果你把任务放在AFTER之后它将安排在它开始运行1分钟后运行,所以它将在1分钟然后2分钟运行,危险的是如果你的任务需要超过1分钟,那么它将直接旋转回来试。
作为一般规则,永远不要仅仅与范围的结尾进行比较,总是与&lt; =或&gt; =进行比较 - 在某些情况下,它不是必需的(例如,如果你一次一个地循环一个循环你不可能错过最后一个)但是这是一个很好的习惯,所以你不能最终得到你没有意识到的情况可以跳过一个。< / p>
以上所说的我确实认为Timer是你最好的选择,我对infomaniac的优秀代码示例进行的唯一优化就是你不需要创建委托引用,它隐含在较新的版本中.NET。
即
Timer stateTimer = new Timer(ListProcesses, null, 0, 60000);
希望有所帮助。