FYI, my fix introduces a deadlock: PipeClient.Read(), if(Connected) causes it to lock PipeClient and attempt to lock UpdateHelper
another thread could be locking UpdateHelper and attempt to lock PipeClient, resulting in deadlock. (this can happen, for example, by UpdateHelper.RetrySend() calling PipeClient.SendMessage()
the fix for this is to make sure pipeClient never calls anything that can end up locking UpdateHelper.Thankfully, this only means changing one function, the PipeClient.Read() which I already described, plus the MessageReceived section of the same .Read() method
the fixed code can be found at http://pastebin.com/b3MzQbSM