gpt4 book ai didi

c# - Thread.Sleep 的替代品

转载 作者:行者123 更新时间:2023-11-30 14:00:49 27 4
gpt4 key购买 nike

在 Windows 服务上工作,它必须在每个预定义的时间间隔内处理请求。 Thread.Sleep 可以很好地完成工作,但问题是调用服务停止时,如果线程处于 sleep 模式,服务会卡住。我已经阅读了像 Timer 这样的替代方法,但问题是在定义的间隔新线程开始之后。有没有更好的方法来实现相同的结果并且不会遇到问题。

最佳答案

您要寻找的是响应两种不同事件通知的能力 - (1) 计时器到时和 (2) 服务停止时。 @Anurag Ranhjan在正确的轨道上 WaitHandle ,但你有两个事件,而不是一个。要正确处理此问题,请执行以下操作。

首先,使用 ManualResetEvent 定义您关心的两个事件.您可以使用 AutoResetEvent如果你更喜欢;我只是更喜欢手动重置事件。

using System.Threading;
ManualResetEvent shutdownEvent = new ManualResetEvent();
ManualResetEvent elapsedEvent = new ManualResetEvent();

您需要在这些事件发生时触发它们。对于 shutdownEvent,这很简单。在 Windows 服务的 OnStop 回调中,只需设置事件即可。

protected override void OnStop
{
shutdownEvent.Set();
}

对于 elapsedEvent,您可以通过几种不同的方式来实现。您可以创建一个后台线程,即 ThreadPool , 使用 Thread.Sleep .当线程醒来时,设置 elapsedEvent 并返回休眠状态。由于它是一个后台线程,它不会在关闭时挂起您的服务。正如您已经建议的那样,另一种方法是使用计时器。我就是这样做的。

using System.Timers;
Timer timer = new Timer();
timer.Interval = 5000; // in milliseconds
timer.Elapsed += delegate { elapsedEvent.Set(); };
timer.AutoReset = false; // again, I prefer manual control
timer.Start();

现在您已经正确设置了事件,将它们放在 WaitHandle 中数组。

WaitHandle[] handles = new WaitHandle[]
{
shutdownEvent,
elapsedEvent
};

不要使用 WaitHandle.WaitOne 方法,而是在 while 循环中使用 WaitHandle.WaitAny 方法,如下所示。

while (!shutdownEvent.WaitOne())
{
switch (WaitHandle.WaitAny(handles))
{
case 0: // The shutdownEvent was triggered!
break;
case 1: // The elapsedEvent was triggered!
Process(); // do your processing here
elapsedEvent.Reset(); // reset the event manually
timer.Start(); // restart the timer manually
break;
default:
throw new Exception("unexpected switch case");
}
}

我已经从我的项目中的生产代码中压缩了这个示例。我知道这种机制有效,但我可能在文章中漏掉了一些东西。如果您有任何问题,请告诉我。

关于c# - Thread.Sleep 的替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9853216/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com