Ensure IsExecuting is false when command completes#714
Conversation
Because ReactiveCommand decrements the in flight count in a Finally block, when we await a command's ExecuteAsync method, it still reports an in-flight count when the await returns. We want to not return until the in-flight count is decremented. This fixes that.
…ce-condition-fix Ensure IsExecuting is false when command completes
|
✨ Thanks @haacked! |
|
Wait, I thought and are semantically the same? Is my whole Rx knowledge a lie? |
|
Damn I know that feeling! |
|
Finally runs after the subscription has been disposed, so it runs after OnCompleted and after OnError. In the following code the Finally action runs after the actions in the Do. .Finally(() => decrement.Disposable = Disposable.Empty)
.Do(
_ => { },
e => decrement.Disposable = Disposable.Empty,
() => decrement.Disposable = Disposable.Empty) |
|
Aha! Makes sense, thanks @jlaanstra! |
|
I need to write a blog post about this - basically Finally interacts badly with await, because the Finally block runs shortly after the awaiter returns. In practice, this almost never matters, but in a unit test, it results in very confused people. Here's the troll scenario that this PR fixes: bool latestIsExecuting;
someCommand.Subscribe(x => latestIsExecuting = x);
await someCommand.ExecuteAsync();
Assert.False(latestIsExecuting); // It's true, whyyyyyyyy |
Not necessarily the case. It's hard to predict whether it'll matter or not. But you could imagine a method that has some common logic and it checks to make sure a command isn't currently executing. You call this method from multiple locations including from the |
Because
ReactiveCommanddecrements the in flight count in aFinallyblock, when we await a command'sExecuteAsyncmethod, it still reports an in-flight count when the await returns. We want to not return until the in-flight count is decremented. This fixes that by putting the decrement in aDostatement for both the onNext block and the onError block.