Marc Gravell said:
Hi again; I'm a convert... kind-of...
I toyed with this on the train, and agree that not only is it a nicer
wrapper around lock, but it offers significant development gain (such as the
named locks, which are invaluable). With some changes (see below) I was able
to use this to successfully identify a deadlock issue (in a highly-threaded
system) that has been bugging me for a while:
Excellent. It's nice to see it being used "in the wild" as it were.
Some more feedback, however, on the knife-edge call about Pulse, Wait etc;
to assist my debugging, I pushed these methods (as private internal virtual)
onto SyncLock, and forwarded them (as public) from LockToken; this allowed
me to put in some #if DEBUG regions around Lock, Unlock, Wait and Pulse
which keep track of the thread currently holding the lock (in a Thread field
that is likewise #if DEBUG). By doing this, when a timeout occurs I can
include verbose information about exactly which 2 threads are competing. A
bit similar to some of OrderedLock, but my code wouldn't lend itself to an
OrderedLock implementation (without significant rework), where-as with
SyncLock it is an issue. As a side-benefit, it would also allow java-like
"do I hold the lock, else who" calls, but I'm not sure it is worth the
overhead except in DEBUG mode.
Right. Unfortunately, the way that debug/release builds work, you'd
have to have two different versions of the library available (or build
it alongside your project). It's not a great situation
Re your thoughts about extensions to Monitor; while I see your point, if
additional functionality is added to Monitor that can't be added to
SyncLock, then a: I'd be suprised (as it would be an equal pain to use in
*any* code - perhaps more as not encapsulated), and b: as a class to do a
specific job, it works very well - so if something *couldn't* be
retro-fitted to SyncLock, then it is probably so esoteric that it wouldn't
want to be.
The problem is a bit more subtle than that though. Suppose .NET 2.1
adds a new method in Monitor:
1) Until I update the source, no-one can use that new method in
conjunction with SyncLock
2) I can't provide a version which works against 1.1/2.0 *and* 2.1,
which would still have all the appropriate methods. Currently I'm just
building against 1.1, and anyone can use the library for 1.1 or 2.0.
I'd rather not get into the business of building multiple versions.
However, all of this rests on Monitor adding methods. I'm tempted to
take the risk...
So, erm, yes; my /personal/ opinion is that this fits a lot better with
Pulse etc on the LockToken, as not only does it allow for a complete locking
solution (encapsulated in one consistent place), but it allows for positive
(debugging) benefit along the way.
(If you want any of my hacks, let me know and I'll e-mail them - but they're
pretty simple to be honest).
If you could mail me the code, it would be handy - I generally find it
easier to understand actual code than descriptions of code
Cheers again for (indirectly, but crucially) helping me fix my [dead]locking
woes ;-p
My pleasure - and let me know if you have any more feedback...