

Solving Likely Problems in Your Multithreaded Code - moks
https://msdn.microsoft.com/en-us/magazine/cc817398.aspx

======
taspeotis
Microsoft's code quality evangelism pains me a bit. With one hand they publish
articles like this and add tools to Visual Studio to help with code quality
(e.g. adding static code analysis to VS2012 Express and later). And with the
other hand they go "haha fuck you" and arbitrarily lock out some code quality
tools unless you're using Visual Studio Ultimate. (my Visual Studio with MSDN
Premium isn't enough, it seems.)

"Smart Unit Tests" [1] is the most recent in a long list of things tucked away
in Ultimate.

[1]
[https://msdn.microsoft.com/library/dn823749(v=vs.140).aspx](https://msdn.microsoft.com/library/dn823749\(v=vs.140\).aspx)

~~~
copsarebastards
This isn't surprising. Microsoft is out to make money, not to make the world's
code quality better. They may make the world's code quality better sometimes,
but if they are faced with a choice between the two, they're going to choose
the money. Visual Studio's tiered pricing and tiered features are just an
example of that.

If making the world's code quality better is a priority for you, I think the
solution is to switch to free languages and toolchains and help improve them.
I'm not saying this from a "shut up or leave" kind of mentality: this is
exactly why I moved out of the C#/.NET ecosystem.

------
rayiner
The bank account example is a classic illustration of the problems with
locking:

    
    
        class BankAccount {
            internal static void Transfer(
              BankAccount a, BankAccount b, decimal delta) {
                Withdraw(a, delta);
                Deposit(b, delta);
            }
            // As before 
        }
    

Withdraw() and Deposit() either do their own locking, and we get a race trying
to use them together, or we push locking up the chain to their users. The
former solution is unacceptable, and the latter just punts the problem--what
if we want to call Transfer() and some other function together without a
possible race condition between them?

~~~
lmm
Create a "box" type, say AccountAction, that represents something that has to
happen atomically. The AccountAction-ness ripples up the chain, so user
functions may return AccountActions, or may call several AccountActions and
return a single combined AccountAction for things like this Transfer. At the
top level there can be a single "actor" that's responsible for processing
accounts that processes AccountActions one at a time; user code passes an
AccountAction[T] and gets back the "unboxed" T, the actor having performed the
action atomically.

Ensure that the only way to construct something that accesses a BankAccount is
as an AccountAction. You're automatically assured that any code calls the
"actor" eventually, because there's no way to e.g. print an
AccountAction[String] to standard output - sooner or later you have to make
the call. User code can still have races if it tries (e.g. if it deliberately
calls the "actor" separately for the withdraw and the deposit), but such code
is much more obviously wrong from reading and looking at the types
(particularly if you call your actor call something like "unsafeTransaction").
If you've got a single consistent point of entry/exit (e.g. this is a message-
processing system), you can put the actor call there.

The only hard part is making this easy enough to use that it doesn't
overcomplicate the code. Provide easy syntax for composing two AccountActions
- something that's as clear and simple as just calling two methods, but with
just enough difference to make it clear from the code whether you're using one
or not - e.g. non-action calls use "=", action calls use "<-". Make a library
of functions for doing things like "perform a list of AccountActions as a
single, atomic AccountAction". Better yet, make AccountAction conform to some
interface such that that library already exists.

(Of course by now you've probably guessed that AccountAction is just an alias
for the reader monad. But the naming is valuable; it keeps everything more
concrete and clear)

------
pc86
(2008)

