If Disconnect throws, `_connectTask` will never complete and the Wait will time out.

If Disconnect throwing is a risk we should probably move `State = ConnectionState.Disconnected;` to the top of the Disconnect so we don't have to worry about the state being unchanged after calling Disconnect. We should also probably put the async `action` call from `ContinueWithNotComplete` in a try/catch and set the `tcs` to faulted if `action` throws. Then, at least, `Connection.Stop` won't hang synchronously for 30 seconds.