In my attempt to use and understand the Lock region, I was trying to create a setup that would crash on purpose so that I could magically fix it using the region.
So I came up with this setup where two threads are adding items to a MutableDictionary (the dictionary itself does not really matter here, could be any mutable collection).
Note that accessing the Count property on the main thread might also get you into trouble when another thread is currently mutating the collection. It depends on the implementation. Probably, in this case, just a field gets read internally, so you might get lucky.
But in general, any access to a mutable object - including read access - should be done in a serial fashion, just to be sure that none of the methods runs into troubles.
Also, note that the collection throwing exceptions is a sugar. Not every object is programmed to behave like that. They just end up in a corrupt state, resulting in errors further down the road. The error will maybe show up hours later when those extra threads are not running anymore.
So it’s very “nice” of this collection to try to detect if it gets accessed by different threads simultaneously.
I know, you know, but just completeness: You could also use
immutable collections and just update the snapshot, which is an atomic operation and therefore threadsafe
use threadsafe collections (concurrent)
But yeah Lock definitely is another candidate. Nice example!
Thank you!
I made up an example without a collection, for fun.
It shows how a custom-patched class gets into a corrupt state / doesn’t do the right thing when accessed by different threads.
In this example, I put 1 million bucks into a Wallet (our patched class). The class only has one property Balance. You might guess that such a simple class can’t get into a corrupt state. It can!
Well here in the example on two threads we are buying stuff in parallel. Each thread buys 500000 items for each 1€. In the end, the balance is not 0 as you would expect.