You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
asynchronous method 'Quartz.Core.QuartzSchedulerThread.Run()', is waiting on a synchronous call to method 'System.Threading.Monitor.Wait(object, int)'
#2354
Open
A9G-Data-Droid opened this issue
May 6, 2024
· 2 comments
· May be fixed by #2373
I have a windows service I wrote in .NET8 that builds Quartz as a hosted service. It works great. It runs things on a schedule. When my service goes to stop it hangs indefinitely, never fully stopping. The final log I see is right before the quartz shutdown line. I have my services ExecuteAsync code wrapped in a try...catch with await _scheduling.Shutdown().ConfigureAwait(false); in the finally to ensure that this is the last thing it does before returning from ExecuteAsync where the host would handle the disposing of Quartz and everything else.
I attached VS2022 debugger to the hung service, exported a dump, and analyzed it in VS2022.
It says AA0001 Thread pool thread or asnchronous task blocked on a synchronous call
1 threads are performing asynchronous work in method 'Quartz.Core.QuartzSchedulerThread.Run()', but are waiting on a synchronous call to method 'System.Threading.Monitor.Wait(object, int)'. This may cause thread pool starvation and hangs.
Potential fix
Do not synchronously wait on Monitors, Events, Tasks, or any other objects that may block your thread. See if you can update the method to be asynchronous.
Put await _scheduling.Shutdown().ConfigureAwait(false); at the end of your ExecuteAsync method inside your Windows service
Service is now hung and can't exit gracefully.
Expected behavior
.Shutdown should either complete or throw.
Additional context
The debugger help text is fairly clear that there is a problem with the async code pathways. Looking at the code for Quartz.Core.QuartzSchedulerThread.Run I do see the usage of lock and Monitor.Wait(sigLock, timeUntilContinue); which do not follow async programming as they are both synchronous. The new way to await a lock in async code is usually SemaphoreSlim
This issue appears to be the reason that AsyncMonitorwas written.
The text was updated successfully, but these errors were encountered:
- Avoid blocking synchronously in async methods
- Ignore new warnings when WONTFIX deferred
- Don't run async methods synchronously if you can avoid it
- Convert ValueTask ToTask if you must run synchronously
- Implement JoinableTask when awaiting from multiple places
quartznet#2354
Possibly related to quartznet#2133
- Avoid blocking synchronously in async methods
- Ignore new warnings when WONTFIX deferred
- Don't run async methods synchronously if you can avoid it
- Convert ValueTask ToTask if you must run synchronously
- Implement JoinableTask when awaiting from multiple places
quartznet#2354
Possibly related to quartznet#2133
Describe the bug
I have a windows service I wrote in .NET8 that builds Quartz as a hosted service. It works great. It runs things on a schedule. When my service goes to stop it hangs indefinitely, never fully stopping. The final log I see is right before the quartz shutdown line. I have my services
ExecuteAsync
code wrapped in a try...catch withawait _scheduling.Shutdown().ConfigureAwait(false);
in the finally to ensure that this is the last thing it does before returning fromExecuteAsync
where the host would handle the disposing of Quartz and everything else.I attached VS2022 debugger to the hung service, exported a dump, and analyzed it in VS2022.
It says
AA0001 Thread pool thread or asnchronous task blocked on a synchronous call
Potential fix
Version used
Quartz (3.8.1)
To Reproduce
await _scheduling.Shutdown().ConfigureAwait(false);
at the end of yourExecuteAsync
method inside your Windows serviceExpected behavior
.Shutdown
should either complete or throw.Additional context
The debugger help text is fairly clear that there is a problem with the async code pathways. Looking at the code for
Quartz.Core.QuartzSchedulerThread.Run
I do see the usage oflock
andMonitor.Wait(sigLock, timeUntilContinue);
which do not followasync
programming as they are both synchronous. The new way to await a lock in async code is usually SemaphoreSlimThis issue appears to be the reason that AsyncMonitorwas written.
The text was updated successfully, but these errors were encountered: