ServiceController.WaitForStatus with multiple desiredStatus
本文关键字:desiredStatus multiple with WaitForStatus ServiceController | 更新日期: 2023-09-27 17:56:54
我目前使用以下方法等待服务启动...
srvCtl.Start();
srvCtl.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 30))
如果服务在启动后立即停止,我也想解释它被停止的原因。
有没有办法同时等待ServiceControllerStatus.Running
和ServiceControllerStatus.Stopped
以下内容可能有点问题,因为任务和线程彼此不太喜欢,但你可以这样做:
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();
希望对您有所帮助!
如果时间跨度在启动之前过期,则 WaitforStatus 会引发超时异常。
您可以在异常处理程序中检查当前和所需状态,并在那里执行您认为合适的任何操作。如果设置的超时足够小,则可以进行测试,然后根据需要退出或重试。
我不相信 WaitforStatus 支持多个同时条件,但让它过期,然后检查似乎非常接近您想要的。
事实证明,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);
}
}