【发布时间】:2023-03-12 10:43:01
【问题描述】:
基本上,我想为外部进程的运行时间计时不是由我的代码触发的。为了实现这一点,我订阅了特定进程开始和结束的事件进程名称,使用以下代码(基于此answer):
private ManagementEventWatcher ProcessStartWatcher(string processName)
{
string queryString =
"SELECT TargetInstance" +
" FROM __InstanceCreationEvent " +
"WITHIN 1 " +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = '" + processName + "'";
// The dot in the scope means use the current machine
string scope = @"\\.\root\CIMV2";
// Create a watcher and listen for events
ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
watcher.EventArrived += ProcessStarted;
watcher.Start();
return watcher;
}
private ManagementEventWatcher ProcessEndWatcher(string processName)
{
string queryString =
"SELECT TargetInstance" +
" FROM __InstanceDeletionEvent " +
"WITHIN 1 " +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = '" + processName + "'";
// The dot in the scope means use the current machine
string scope = @"\\.\root\CIMV2";
// Create a watcher and listen for events
ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
watcher.EventArrived += ProcessEnded;
watcher.Start();
return watcher;
}
private void ProcessStarted(object sender, EventArrivedEventArgs e)
{
this.processStart = DateTime.Now;
}
private void ProcessEnded(object sender, EventArrivedEventArgs e)
{
// use time recorded from ProcessStarted to calculate run duration, write to log file
this.logger.addRuntimeData((DateTime.Now - this.processStart).TotalSeconds);
}
addRuntimeData(double seconds) 方法定义为:
public void addRuntimeData(double seconds)
{
this.runDurations.Add(seconds);
if (this.runDurations.Count > Properties.Settings.Default.MaxRunDurationData)
this.runDurations.RemoveAt(0);
this.updateLog();
}
public void updateLog()
{
this.logfileDirectory = Properties.Settings.Default.LogfileDirectory;
this.logfileFullPath = logfileDirectory + this.task.Name.toValidFilename() + this.logfileExtension;
Directory.CreateDirectory(logfileDirectory); // create directory if it does not already exist
this.toXElement().Save(this.logfileFullPath); // generate the XML and write it to the log file
}
现在,我只是在尝试为我编写的测试过程计时,所有测试过程所做的只是对Console.WriteLine("Test process"); 的一次调用,因此记录持续时间的适当值应大致在 0-2 秒范围内.
有时, 我得到的值是适当的,有时我得到的值实际上是不可能被记录下来的,例如 63619141321.2978 秒。这大约等于 2017.3 年,这让我认为它可能与开始时间被记录为 01/01/0001 00:00:01 或类似的东西有关;这个问题有可能与此有关吗?
如果这是一个我无能为力的问题(例如,如果它与操作系统触发消息的方式/时间有关),有没有办法可以过滤掉这些明显无效的数据积分?
【问题讨论】:
-
Bobby Tables 或许能告诉你。
-
@MattRowland lol rekt savage
-
可能是因为在
ProcessStarted被触发并初始化processStart之前记录了一个持续时间。 -
这里很可能结束事件出现在开始事件之前。观察者只是在投票。 “WITHIN 1”子句的目的是设置轮询间隔。有时,最终进程观察者设法首先捕获其事件。如果开始时间没有初始化,那么它会给你你所看到的。
-
@mikez 那么在
ProcessEndWatcher中将WITHIN 1更改为WITHIN 2可以解决此问题,因为由于ProcessStartWatcher设置为WITHIN 1,这将确保结束事件不是在开始事件之前触发?
标签: c# validation process filtering