reactiveui/ReactiveUI — pull request #521 by paulcbetts (2014-02-17 08:26:15+00:00)
Title: Rewrite ReactiveCommand

This PR is a full rewrite from the ground up of ReactiveCommand to make it more friendly to asynchronous operations. In RxUI 5.x, the following things are Hard™ and shouldn't be:

* Executing a command and waiting for its associated async actions to complete
* Creating a command that invokes several other commands and waits for them to complete (i.e. if I have a `SyncRemoteData` command and a `LoadAvatarsForLocalData` command, it's really difficult to correctly write a `SyncRemoteDataAndLoadTheAvatars` command).

### Philosophy

The core issue behind this? `void ICommand.Execute(object parameter)`. Methods that kick off async operations but return void suck. Instead, we add a new method, `IObservable ExecuteAsync(object parameter)`. This signals completion and error status for a *single* invocation of Execute, whereas `RegisterAsync` only gave us the stream of final values, making it impossible to pick out a single invocation.

To do this though, we had to make `ReactiveCommand` a Generic type. This has advantages, because we can now get the same stream of data that we originally did from `RegisterAsync`, but by Subscribing to the command itself. The disadvantage is that we have the "noise" of always having to set templates.

We get around this, via a set of `Create` methods, which can infer the template type based on the passed in parameters.

### Bring it all together

Old:
```cs
var canExecute = this.WhenAny(x => x.Name, x => !String.IsNullOrEmpty(x.Value));

ReactiveCommand LookUpUser = new ReactiveCommand(canExecute);
LookUpUser.RegisterAsync(_ => FetchUser(this.Name))
.Subscribe(x => this.UserInfo = x);

// Look up a user and wait for it to show up
LookUpUser.Execute(null);
await LookUpUser.IsExecuting.Where(x => x == false).Take(1);
```

New:
```cs
var canExecute = this.WhenAny(x => x.Name, x => !String.IsNullOrEmpty(x.Value));
ReactiveCommand LookUpUser = ReactiveCommand.Create(canExecute, _ => FetchUser(this.Name));
LookUpUser.Subscribe(x => this.UserInfo = x);

// Look up a user and wait for it to show up
var userInfo = await LookUpUser.ExecuteAsync();
```

### Disadvantages

* We no longer ever allow concurrent execution - if you want this, just create a default ReactiveCommand and do `SelectMany` on it.
* You can no longer register multiple async actions on a command. Pretty sure nobody cares.
* `ReactiveCommand