-1

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

4

5 回答 5

4

就个人而言,我会为此坚持使用计时器。它真的很优雅。但是,如果你真的想要一些更有活力的东西,那么请继续阅读!

随着新关键字asyncawait关键字(将包含在 C# 5.0 中)的流行,我们可能会看到计时器变得越来越不酷1这是您现在使用Async 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);
    }
  }
}

很奇怪吧?它可能不是如何async以及应该如何await使用的理想示例,但您明白了。这是未来的浪潮。


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

于 2012-04-13T02:35:01.067 回答
1

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

    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.

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

于 2012-04-13T02:41:55.880 回答
0

如果您不使用计时器,您将需要执行以下操作:

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

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

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

于 2012-04-13T02:07:15.930 回答
0

程序1:

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

正在运行的进程被添加到 observablecollection 中。每当添加一个项目时,它都会引发 CollectionChanged 事件。

程序2:

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

于 2012-04-13T02:22:03.380 回答
0

我不同意认为 Timers 是这里唯一或最佳答案的评论。当变化发生时希望得到警报,而不是轮询它,这是一种崇高的追求。我相信您正在寻找一个 WinAPI “Hook”,但我不知道是哪一个或它是否存在。

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

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

于 2012-04-13T02:30:25.647 回答