ASP.NET Core 6 - Strange Monitor.TryLock behavior
Hi,
I'm making some experiment to better understand the Monitor. Looks like something is off: I've written the following code
And I have this strange (apparently) result:
At first I couldn't understand this strange behavior. Now I've noticed that Monitor.Try enter description says "returns true if the current thread acquires the lock". From my understanding, Task.Run may or may not create a new thread, so for example task 0 and task 2 could have been executed inside the same thread, and this would explain why task 2 entered the monitor even though it should have been acquired by task 0.
What do you think? is this the correct explanation?
If that's the case, it seems to me Monitor is not suitable for protect a resource from multiple-task access
3 Replies
I think your explanation might be correct. You can try also logging the
Thread.CurrentThread.ManagedThreadId
to confirm it is the same thread.
By doing await Task.Delay()
, .NET frees up the current thread and just makes it so any thread will pick up the work when the delay is completed.
Also depending on the TaskScheduler and Synchronization Contexts of the current application, the thread that continues after the Task.Delay might not be the same thread that aquired the monitor (so a different thread might exit the Monitor) but I'm not sure if that's the case here
I think that would throw exceptionsYeah, looks to be an issue with mixing
Monitor
and async
. The top two answers here are good: https://stackoverflow.com/questions/21410320/monitor-tryenter-doesnt-workI didn't though about the problem "the thread that continues after the Task.Delay might not be the same thread that aquired the monitor", that would explain why in the previous version of the code, where I had a try-catch block, sometimes it happened that task number x would acquire the lock and, after sleeping, it could not acquire the lock. I'm gonna check again since I don't remember precisely
Thanks