Below is a sample app that I have written to reproduce the problem. I am using ReactiveUi 7.0.
Command is repeatedly invoked whenever I change the text it in the TextBox. However, if there is an exception thrown from the command (it is captured properly by the lambda of Search.ThrownExceptions.Subscribe), further invocation of the command is not happening if I change the TextBox text.
MainWindow.xaml
<Window x:Class="SampleTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SampleTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<!--<controls:ProgressRing Grid.Column="0" Width="20" Height="20" ></controls:ProgressRing>-->
<TextBox Margin="8 0 0 0" x:Name="SearchBox" MinWidth="200" VerticalAlignment="Center" Text="{Binding SearchQuery, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Window>
ViewModel.cs
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SampleTest
{
internal class ViewModel : ReactiveObject
{
private SearchService service = new SearchService();
public ReactiveCommand<string, string> Search { get; set; }
private string searchQuery;
public string SearchQuery
{
get { return this.searchQuery; }
set { this.RaiseAndSetIfChanged(ref this.searchQuery, value); }
}
public ViewModel()
{
Search = ReactiveCommand.CreateFromTask(async (string query) =>
{
var r = await this.service.SearchQuery(query, 100);
return r;
});
Search.Subscribe(
results =>
{
});
this.WhenAnyValue(x => x.SearchQuery)
.Throttle(TimeSpan.FromMilliseconds(250), RxApp.MainThreadScheduler)
.InvokeCommand(this, x => x.Search);
Search.ThrownExceptions
.Subscribe(ex =>
{
//this.ErrorInteraction.Handle($"Whilst searching, {ex.Message}");
});
}
}
}
SearchService.cs
internal class SearchService
{
public async Task<string> SearchQuery(string searchQuery, int size = 50)
{
return await Task.Run(() =>
{
throw new Exception("something is wrong");
return "";
});
}
}