如何等待将要开始的流程?

时间:2011-07-04 18:51:06

标签: c# synchronization wait

我的应用程序需要等到特定进程开始。我是这样做的

while (Process.GetProcessesByName("someProcess").Length == 0)
{
    Thread.Sleep(100);
}

有没有其他方法(更优雅)如何实现这一点,功能类似于WaitForExit()?谢谢你的回答。

2 个答案:

答案 0 :(得分:8)

查看ManagementEventWatcher课程。

具体来说,链接底部的代码示例显示了如何设置ManagementEventWatcher以在创建新进程时收到通知。

从MSDN代码示例中复制的代码(可以稍微清理一下):

using System;
using System.Management;

// This example shows synchronous consumption of events. 
// The client is blocked while waiting for events. 

public class EventWatcherPolling 
{
    public static int Main(string[] args) 
    {
        // Create event query to be notified within 1 second of 
        // a change in a service
        WqlEventQuery query = 
            new WqlEventQuery("__InstanceCreationEvent", 
            new TimeSpan(0,0,1), 
            "TargetInstance isa \"Win32_Process\"");

        // Initialize an event watcher and subscribe to events 
        // that match this query
        ManagementEventWatcher watcher =
            new ManagementEventWatcher();
        watcher.Query = query;
        // times out watcher.WaitForNextEvent in 5 seconds
        watcher.Options.Timeout = new TimeSpan(0,0,5);

        // Block until the next event occurs 
        // Note: this can be done in a loop if waiting for 
        //        more than one occurrence
        Console.WriteLine(
            "Open an application (notepad.exe) to trigger an event.");
        ManagementBaseObject e = watcher.WaitForNextEvent();

        //Display information from the event
        Console.WriteLine(
            "Process {0} has been created, path is: {1}", 
            ((ManagementBaseObject)e
            ["TargetInstance"])["Name"],
            ((ManagementBaseObject)e
            ["TargetInstance"])["ExecutablePath"]);

        //Cancel the subscription
        watcher.Stop();
        return 0;
    }
}

修改

添加了TargetInstance.Name = 'someProcess'过滤器的简化示例。

  var query = new WqlEventQuery(
                "__InstanceCreationEvent", 
                new TimeSpan(0, 0, 1), 
                "TargetInstance isa \"Win32_Process\" and TargetInstance.Name = 'someProcess'"
              );

  using(var watcher = new ManagementEventWatcher(query))
  {
    ManagementBaseObject e = watcher.WaitForNextEvent();

    //someProcess created.

    watcher.Stop();
  }

答案 1 :(得分:2)

据我所知,Process课程中没有任何内容可以简化。

如果您无法控制子流程中的源代码,那么您应该使用Calgary Coder提供的WMI解决方案。

如果您确实控制了子流程中的代码,那么还有一些其他方法可以解决此问题。我使用了WCF(使用an IPC binding),.Net RemotingMutex

这些解决方案的优点是子流程必须选择它。在允许父应用程序知道它已“准备好”之前,子进程可以自由等待它完成启动初始化例程。

每个链接都有一些示例,可以帮助您解决此问题。如果您有兴趣选择特定问题并遇到问题,请告诉我,我会为该特定解决方案发布一些示例代码。