我目前使用以下内容等待服务启动...
srvCtl.Start();
srvCtl.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 30))
如果某个服务在启动后立即停止,我也想说明它被停止了。
有没有办法等待ServiceControllerStatus.Running
和ServiceControllerStatus.Stopped
答案 0 :(得分:1)
以下可能有点问题,因为任务和线程彼此不太喜欢,但你可以这样做:
CancellationTokenSource cts = new CancellationTokeSource();
List<Task> tasks = new List<Task>
{
Task.Run(()= > srvCtl.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 30)), cts),
Task.Run(()= > srvCtl.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 30)), cts),
...
}
// When any of the tasks completes, it means the service reached on of the statuses you were tracking
await Task.WhenAny(tasks);
// To cancel the rest of the tasks that are still waiting
cts.Cancel();
希望它有所帮助!
答案 1 :(得分:0)
如果在启动之前的时间跨度,WaitforStatus会抛出超时异常。
您可以在异常处理程序中检查当前和所需的状态,并执行您认为合适的任何操作。如果设置足够小的超时,则可以进行测试,然后根据需要退出或重试。
我不相信WaitforStatus支持多个同步条件,但让它过期,然后检查似乎非常接近你想要的。
答案 2 :(得分:0)
事实证明,ServiceController.WaitForStatus
什么也不做,只是每0.25秒检查一次服务是否处于所需状态。 (来源:.NET Framework代码的反编译。)因此,如果尝试等待瞬态,则可能会错过它。因此,创建多个任务(和线程)以等待每个状态都是一个过大的选择。只需重现实际的.NET代码并更改返回条件即可。
public static ServiceControllerStatus WaitForStates(this ServiceController service, TimeSpan timeout, params ServiceControllerStatus[] states)
{
//parameter checks omitted
DateTime start = DateTime.UtcNow;
while (true)
{
service.Refresh();
ServiceControllerStatus currentState = service.Status;
if (states.Contains(currentState))
return currentState;
TimeSpan elapsedTime = DateTime.UtcNow - start;
if (elapsedTime > timeout)
throw new TimeoutException();
Thread.Sleep(250);
}
}