Search code examples
c#.netthread-sleep

Better ways to block execution in polling wait loop?


I am writing a library that communicates with several WCF endpoints. In many cases, I have to wait for a particular state or condition on the remote service. I have written a simple polling wait loop which looks something like this:

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();
}

After reading several posts about how Thread.Sleep is a sign of a poorly designed program, I'm reevaluating every place I've used it. I'm struggling with the best way to replace its usage in this wait loop. I've seen recommendations to use Task.Delay, but since I have to block execution I think I would have to use Task.Delay(checkInterval).Wait() which doesn't seem to provide the typical advantages of tasks.

I'm aware of the advantages of using a callback/event-based WCF method, rather than polling, but unfortunately I am unable to modify the service endpoints to expose this kind of functionality.

My library does not make use of any multi-threading, but I would like it to be friendly to consumers that may wish to multi-thread their applications.

Is replacing Thread.Sleep with Task.Delay.Wait() the way to go, or are there better ways to implement a blocking wait loop?


Solution

  • Since you can't be notified by the service when the event that you are looking for happens polling is the best you can do.

    If you have a lot of these polling loops running at the same time consider using async waiting to release threads. That requires using, for example,

    await Task.Delay(...);
    

    and making the polling method and the entire call chain async.

    This is a waste of dev time if there are just a few such polling loops.

    Sleeping is fine for purposes of timing which you are doing here.