I\'ve got the following scenario, which I think might be quite common:
There is a task (a UI command handler) which can complete either synchronously or asy
Microsoft's Rx does provide an easy way to do this kind of thing. Here's a simple (perhaps overly simple) way of doing it:
var subject = new BehaviorSubject(0);
IDisposable subscription =
subject
.Scan((x0, x1) =>
{
Console.WriteLine($"previous value {x0}");
return x1;
})
.Skip(1)
.Subscribe(x => Console.WriteLine($"current value {x}\r\n"));
subject.OnNext(1000);
subject.OnNext(900);
subject.OnNext(800);
Console.WriteLine("\r\nPress any key to continue to test #2...\r\n");
Console.ReadLine();
subject.OnNext(200);
subject.OnNext(100);
Console.WriteLine("\r\nPress any key to exit...");
Console.ReadLine();
The output I get is this:
previous value 0 current value 1000 previous value 1000 current value 900 previous value 900 current value 800 Press any key to continue to test #2... previous value 800 current value 200 previous value 200 current value 100 Press any key to exit...
It's easy to cancel at any time by calling subscription.Dispose().
Error handling in Rx is generally a little more bespoke than normal. It's not just a matter of throwing a try/catch around things. You also can repeat steps that error with a Retry operator in the case of things like IO errors.
In this circumstance, because I've used a BehaviorSubject (which repeats its last value whenever it is subscribed to) you can easily just resubscribe using a Catch operator.
var subject = new BehaviorSubject(0);
var random = new Random();
IDisposable subscription =
subject
.Select(x =>
{
if (random.Next(10) == 0)
throw new Exception();
return x;
})
.Catch(ex => subject.Select(x => -x))
.Scan((x0, x1) =>
{
Console.WriteLine($"previous value {x0}");
return x1;
})
.Skip(1)
.Subscribe(x => Console.WriteLine($"current value {x}\r\n"));
Now with the .Catch it inverts the value of the query should an exception be raised.
A typical output may be like this:
previous value 0 current value 1000 previous value 1000 current value 900 previous value 900 current value 800 Press any key to continue to test #2... previous value 800 current value -200 previous value -200 current value -100 Press any key to exit...
Note the -ve numbers in the second half. An exception was handled and the query was able to continue.