J2N icon indicating copy to clipboard operation
J2N copied to clipboard

System.Threading.Thread.Sleep method does not sleep for milliseconds specified in certain cases

Open laimis opened this issue 1 year ago • 1 comments

ThreadJob class uses System.Threading.Thread.Sleep, which has issues sleeping the right number of milliseconds provided in certain scenarios. For more information please see:

https://stackoverflow.com/questions/19066900/thread-sleep1-takes-longer-than-1ms

We discovered this issue in Lucene.NET repo with some slow running tests and the discussion for that can be seen here:

https://github.com/apache/lucenenet/pull/838

laimis avatar Apr 23 '23 03:04 laimis

This implementation seems to work in the case of https://github.com/apache/lucenenet/pull/838.

internal static void Sleep(int milliseconds)
{
    long ticks = (long)((Stopwatch.Frequency / (double)1000) * milliseconds); // ticks per millisecond * milliseconds = total delay ticks
    long initialTick = Stopwatch.GetTimestamp();
    long targetTick = initialTick + ticks;
    while (Stopwatch.GetTimestamp() < targetTick)
    {
        Thread.SpinWait(1);
    }
}

However, we need to confirm that Thread.SpinWait() will throw a ThreadInterruptedException when Thread.Interrupt() is called by another thread. Unfortunately, the docs for the Thread.Sleep() method don't mention the exception even though it is definitely thrown here, so it is also unclear whether Thread.SpinWait() will throw this.

The TestThreadInterruptDeadlock() test sets up a scenario to force this to happen (which is not very easy to do). We can use it to confirm whether the ThreadInterruptedException is thrown and if not, verify a potential solution for doing so.

After the ThreadJob.Sleep() overloads are fixed with a more precise implementation, Lucene.NET should use it instead of Thread.Sleep() in most (if not all) cases. This is used mostly in tests, but there are also a few IndexWriter and other production code calls where this might be of benefit.

NightOwl888 avatar Apr 23 '23 04:04 NightOwl888