除了在 c# 中使用计时器

本文关键字:计时器 | 更新日期: 2023-09-27 18:30:52

我正在尝试编写一个程序,该程序可以继续执行方法而无需使用计时器。例如,我想要一个显示当前正在运行的进程列表的程序。显然,它是在不断变化的。我不想使用每秒获取进程列表并将它们添加到列表中的计时器,因为它对我来说看起来不是很优雅。有什么特别的方法可以做到这一点吗?我怎样才能使服务能够实现这一目标?

除了在 c# 中使用计时器

就个人而言,我会为此坚持使用计时器。它真的非常优雅。但是,如果您真的想要更多 pizazz 的东西,请继续阅读!

随着新的asyncawait关键字(将包含在 C# 5.0 中)流行起来,我们可能会看到计时器变得越来越不酷1。以下是您现在使用异步 CTP 在没有计时器的情况下执行此操作的方法。

private async void ShowProcessesButton_Click(object sender, EventArgs args)
{
  while (true)
  {
    await Task.Delay(1000);  // TaskEx.Delay in the CTP
    YourListBox.Items.Clear();
    foreach (Process p in Process.GetProcesses())
    {
      YourListBox.Items.Add(p.ProcessName);
    }
  }
}

很奇怪吧? 这可能不是如何使用asyncawait的理想示例,但您明白这一点。这是未来的浪潮。


1不要误会我的意思。总是需要传统的计时器类。

您可以使用无限(直到进程退出)循环生成优先级较低的线程,以定期更新进程列表。如果没有有关您正在使用哪种控件的更多信息或任何信息,我无法真正帮助您解决控件更新委托,但您的函数的粗略骨架将是:

    private void processUpdater()
    {
        while (true) //not the most elegant way to implement a pseudo-infinite loop, but you can figure out how you want to signal it to end.
        {
            var runningProcesses = Process.GetProcesses().Where(p => !string.IsNullOrEmpty(p.MainWindowTitle)).Select(p => p.MainWindowTitle); //filter the running processes to get those with open windows.
            this.lstProcesses.Invoke((MethodInvoker)delegate { this.lstProcesses.Items.Clear(); }); //thread-safe invocation to clear the current items
            this.lstProcesses.Invoke((MethodInvoker)delegate { this.lstProcesses.Items.AddRange(runningProcesses.ToArray<string>()); }); //add the new set of windowed processes
            System.Threading.Thread.Sleep(5000); //update the list every 5 seconds
        }
    }

就我而言,我只是使用窗口捕获进程,并在列表框中列出这些窗口标题(lstProcesses)

现在,生成此线程:

var tUpdater = new System.Threading.Thread(processUpdater);
tUpdater.Priority = System.Threading.ThreadPriority.BelowNormal;
tUpdater.Name = "Process List Updater";
tUpdater.Start(); //start the thread running.

显然,这是一个非常基本的实现,但希望它能让你大致了解如何做你想做的事情。

如果你对不使用计时器一无所知,你需要做如下的事情:

  1. 在应用启动时获取列表或正在运行的进程
  2. 检测进程何时启动并将其添加到列表中
  3. 检测进程何时结束并将其从列表中删除

要检测进程创建/终止,请查看以下答案:

https://stackoverflow.com/a/3556280/64290

我不同意有人认为计时器是这里唯一或最好的答案。 当变化发生时,渴望得到警觉,而不是为它投票,是一种崇高的追求。 我相信你正在寻找一个WinAPI"钩子",但我不知道是哪一个或它是否存在。

请参阅 http://msdn.microsoft.com/en-us/library/windows/desktop/ms644959%28v=vs.85%29.aspx

另外:Win API:挂钩每个窗口显示或进程执行

Program1:

您可以开发一个持续运行的Windows服务。不需要计时器。如果您能给我们更多细节,我们可以提出更好的解决方案。但请记住,窗口服务无法进行用户交互。

正在运行的进程将添加到可观察集合中。添加项时,它会引发 CollectionChanged 事件。

程序2:

您可以有一个程序,您希望在其中将正在运行的进程列表公开为 Web 服务,Web 服务在程序 1 中使用。在程序 1 的 CollectionChanged 事件处理程序中,可以调用程序 2 Web 服务并通知新添加的进程。