Hangfire Pro - Redis Error - Safe handle has been closed

Tags: #<Tag:0x00007f1856468640> #<Tag:0x00007f1856468528>

Hi

Latly we have been noticing this error showing in our logs, doesn’t cause any major issues i think hangfire will just retry and starts to work but would like to know if anyone seen any similar issues, why its happening and if anyone has a solution. Unfortunately i cannot replicate at will just randomly happens.

Error Message:
Error occurred during execution of ‘ServerWatchdog’ process. Execution will be retried (attempt #3) in 00:00:09 seconds.
Exception message:
Safe handle has been closed

Stack Trace:
at System.Threading.WaitHandle.WaitOneNative(SafeHandle waitableSafeHandle, UInt32 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext) at System.Threading.WaitHandle.InternalWaitOne(SafeHandle waitableSafeHandle, Int64 millisecondsTimeout, Boolean hasThreadAffinity, Boolean exitContext) at System.Threading.WaitHandle.WaitOne(TimeSpan timeout, Boolean exitContext) at System.Threading.WaitHandle.WaitOne(TimeSpan timeout) at Hangfire.Pro.Redis.RedisStorage.GetDatabase() at Hangfire.Pro.Redis.RedisConnection.RemoveTimedOutServers(TimeSpan timeOut) at Hangfire.Server.ServerWatchdog.Execute(BackgroundProcessContext context) at Hangfire.Server.AutomaticRetryProcess.Execute(BackgroundProcessContext context)

I noticed their are different messages actually

Error occurred during execution of ‘DelayedJobScheduler’ process. Execution will be retried (attempt #3) in 00:00:06 seconds.
Error occurred during execution of ‘ServerHeartbeat’ process. Execution will be retried (attempt #3) in 00:00:04 seconds.
Error occurred during execution of ‘Worker #930f42f7’ process. Execution will be retried (attempt #3) in 00:00:09 seconds.

What i am guessing is Redis is the issue but any feedback will be appreciated

Somewhere in your application the RedisStorage.Dispose method is called explicitly or implicitly, while processing server is active. I’ve just added a check to throw ObjectDisposedException instead of this one for better reasoning (will be released within the next version), but anyway storage should be disposed in a deterministic way so you can just ignore this exception.