I've been chugging along with Noborizaka 2, at a slowish pace (life is hard, okay, there's lots of night markets to visit!)
So I'm going all-out bestpractice and lovely new hotness with this version, and before today I had it going pretty well with PCL (so I can spin up a Win 8 version in the future, faster), and using async for minimal UI blockages...
And then I started getting errors when mashing actions that were calling the database concurrently. I figured it had to be some sort of synchronicity issue as repeating the same actions would persist different data (if it didn't crash). So putting two and two together, since most of my database calls were async now, they weren't necessarily going to not affect each other, especially if it happens to try a read and a write operation at the same time, which LINQ to SQL didn't quite like.
The first thing I tried was wrapping each method call with Monitor.Enter() and .Exit(), but this seemed to lock up the whole application when I ran it. Turns out the reason is that you can't have async calls within Monitored blocks, and I was locking far too large a chunk of code in the first place. I switched to lock() statements, moved them so they were inside the async calls (not surrounding them) and voila! Everything just started working lovely.
TLDR version of this post:
- To prevent concurrency issues, consider locking calls to your database if you're using async
- Unless you have to, stick with lock() instead of Monitor.Enter / Exit or you will fall into this trap
I guess it could have been worse, it could have been cross process Mutexes again!
Footnote: there is probably some property or something I could have set for the LINQ to SQL database to prevent it from crying about having to do a read operation while still doing a write - if you know it I'd love to know - but I figured it would be best practice to just lock it anyway...