Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report on
GitHub or Developer Community with
your current version information, steps to reproduce, and relevant error
messages or log files if you are hitting an issue that looks similar to
this resolved bug and you do not yet see a matching new report.
I am using Monodevelop on Windows Vista.
I build a following code by .NET Runtime.
Then, 'True' is displayed in 3 second later.
Next, I build by mono2.10.5 runtime.
And I execute it. But 'False' is displayed in console immediately.
Monitor.Wait should wait until other thread send pulse
And Monitor.Wait should return 'True' before 10 second past.
static object lockObj = new object();
public static void Main (string args)
new Thread(new ThreadStart(Async)).Start();
Thread.Sleep(3 * 1000);
static void Async()
Console.WriteLine(Monitor.Wait(lockObj, 10 * 1000));
This works-for-me on linux using either HEAD or 2.10.
I think this issue occur on windows only.
Because Monitor class use win32 api.
I can't reproduce with 2.10.2 on windows 7 x64 either.
I find out one new things.
That code return false in debug run.
But it return true in normal run.
Looks like this is caused by the QueueUserAPC call in debugger-agent.c:2529, which happens only on Windows.
This call causes all threads in an alertable wait state to return immediately with WAIT_IO_COMPLETION. That's why Sleeps, Monitors, locks, etc all act crazy when debugging on Windows.
I can remove this QueueUserAPC call, and it works correctly as long as breakpoints aren't set, in which case the debugger hangs. I'm new to this whole codebase, does anybody have any ideas where I should look next?
We use that call to suspend threads, the apc checks whenever we are in managed code or not. If we are in managed code, we suspend, if we are not, we let the thread continue. So it cannot be removed.
I have submitted a patch which resolves this problem, and a few other related ones. Turns out that Semaphores, WaitHandle.*, and Thread.Join also had the same problem. Monitor.Enter/TryEnter was working fine.
The fix was to make sure that after a WaitForSingleObjectEx/WaitForMultipleObjectsEx is interrupted by QueueUserAPC, to re-enter the wait, after calculating the elapsed time and updating the timeout.