Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在轮询等待循环中阻止执行的更好方法?_C#_.net_Thread Sleep - Fatal编程技术网

C# 在轮询等待循环中阻止执行的更好方法?

C# 在轮询等待循环中阻止执行的更好方法?,c#,.net,thread-sleep,C#,.net,Thread Sleep,我正在编写一个与多个WCF端点通信的库。在许多情况下,我必须等待远程服务的特定状态或条件。我编写了一个简单的轮询等待循环,如下所示: private bool WaitForTrue(Func<bool> action, TimeSpan waitTime, TimeSpan checkInterval) { DateTime end = DateTime.UtcNow + waitTime; while (DateTime.UtcNow < end)

我正在编写一个与多个WCF端点通信的库。在许多情况下,我必须等待远程服务的特定状态或条件。我编写了一个简单的轮询等待循环,如下所示:

private bool WaitForTrue(Func<bool> action, TimeSpan waitTime, TimeSpan checkInterval)
{
    DateTime end = DateTime.UtcNow + waitTime;
    while (DateTime.UtcNow < end)
    {
        if (action())
        {
            return true;
        }
        Thread.Sleep(checkInterval);
    }

    return action();
}
private bool WaitForTrue(Func操作、TimeSpan waitTime、TimeSpan checkInterval)
{
DateTime end=DateTime.UtcNow+waitTime;
while(DateTime.UtcNow
在阅读了
Thread.Sleep
是一个设计糟糕的程序的标志后,我正在重新评估我使用过它的每个地方。我正在努力寻找在这个等待循环中替换它的最佳方法。我看到过使用
Task.Delay
的建议,但由于我必须阻止执行,我认为我必须使用
Task.Delay(checkInterval).Wait()
,它似乎没有提供任务的典型优势

我知道使用基于回调/事件的WCF方法而不是轮询的优点,但不幸的是,我无法修改服务端点以公开此类功能

我的库不使用任何多线程,但我希望它对希望多线程应用程序的用户友好


Task.Delay.Wait()
替换
Thread.Sleep
,或者有更好的方法来实现阻塞等待循环吗?

您可以通过等待一个从未收到信号的互斥体来避免
Thread.Sleep
。例如,为自己设置一个互斥锁,并使用其中一个需要时间跨度的互斥锁

private bool WaitForTrue(
    Func<bool> action, TimeSpan waitTime, TimeSpan checkInterval)
{
    using(var mutie = new Mutex())
    {
        DateTime end = DateTime.UtcNow + waitTime;
        while (DateTime.UtcNow < end)
        {
            if (action())
            {
                return true;
            }
            mutie.WaitOne(checkInterval);
        }    
        return action();
    }
}
private bool WaitForTrue(
Func操作、TimeSpan等待时间、TimeSpan检查间隔)
{
使用(var mute=new Mutex())
{
DateTime end=DateTime.UtcNow+waitTime;
while(DateTime.UtcNow
我不相信这样做实际上意味着你比那些使用线程的程序员更好


(经过一点研究后)似乎是
Task.Delay
释放当前线程,然后稍后在(可能的)另一个线程上重新启动执行。这绝对比睡觉(锁定线程)好(释放线程)。如果您在执行过程中已经在使用任务,并且不特别需要阻止当前线程,那么您最好选择
Task.Delay

因为当您正在查找的事件发生时,服务无法通知您轮询是您能做的最好的选择

如果你有很多这些轮询循环同时运行,考虑使用异步等待发布线程。这需要使用,例如

await Task.Delay(...);
使轮询方法和整个调用链异步

如果只有几个这样的轮询循环,这将浪费开发人员的时间


睡眠对于你在这里进行的计时来说是很好的。

为什么不设置一个计时器并在其事件上执行该函数呢?@Ewan我也看到了这个建议,但我很难想象它是如何工作的。您是否介意发布一个带有示例的答案?因此您正在轮询一个远程服务,而该服务无法通知您?@usr没错,该服务不支持任何回调机制。在大多数情况下,我正在调用服务,这将导致它(最终)改变状态,但我必须再次查询该服务以查看当前状态。为什么不将其发挥到极致并使用Rx呢。创建一个主题以向订阅者广播更改?@JohnTaylor Dunno。过度杀戮?你可以随时在deets中添加答案。我仍在理解Rx的过程中。Rx和Tasks会导致一些非常复杂的线程执行,但它们可以消除所有等待和休眠,这就是问题的关键所在。如果Task.Delay做了同样的事情,只是更好的线程。休眠总是以更好的方式完成。互斥体也是如此。@usr“如果Task.Delay做了同样的事情,它只是一个更好的线程。睡眠总是能以更好的方式完成。”这到底是什么意思?你没有读过关于释放当前线程(Task.Delay)和阻塞当前线程(thread.Sleep)的文章吗?你真的认为框架团队会完全改变线程的行为吗?我完全被这种想法弄糊涂了。