Switch vs SelectMany + TakeUntil - system.reactive

I'm writing an operator that effectively does the same as Switch plus some other stuff. I always understood Switch to effectively be a neat wrapper around SelectMany combined with TakeUntil. However whilst implementing my new extension I've noticed something different about the order of creation/disposal of inner sequences. I'm wondering how I can replicate the order Switch works in since it seems likely we'd always want to dispose the existing inner before creating a new one.
I've written 2 tests to illustrate what I mean.
StandardSwitch will give the following output:
Disposing Inner followed by Creating New Inner
HandCrankedSwitch will give:
Creating New Inner,
Disposing Inner
See example code below:
[TestMethod]
public void StandardSwitch()
{
var outer = Observable.Interval(TimeSpan.FromSeconds(1))
.Do(x => Console.WriteLine("New Outer Value is {0}", x));
var wait = new CountdownEvent(8);
outer
.Select(CreateInner)
.Switch()
.Subscribe(x =>
{
Console.WriteLine("Subscriber Got {0}", x);
wait.Signal();
});
wait.Wait();
Console.WriteLine("Done");
}
[TestMethod]
public void HandCrankedSwitch()
{
var outer = Observable.Interval(TimeSpan.FromSeconds(1))
.Do(x => Console.WriteLine("New Outer Value is {0}", x));
var wait = new CountdownEvent(8);
outer.Publish(x => x.Select(CreateInner).SelectMany(xs => xs.TakeUntil(x)))
.Subscribe(x =>
{
Console.WriteLine("Subscriber Got {0}", x);
wait.Signal();
});
wait.Wait();
Console.WriteLine("Done");
}
internal IObservable<long> CreateInner(long notUsed)
{
return Observable.Create<long>(obs =>
{
Console.WriteLine("Creating New Inner");
var compDis = new CompositeDisposable {Disposable.Create(() => Console.WriteLine("Disposing Inner"))};
var dis = Observable.Interval(TimeSpan.FromSeconds(0.4))
.Do(x => Console.WriteLine("New Inner Value is {0}", x))
.Subscribe(obs);
compDis.Add(dis);
return compDis;
});
}

Related

Query with `groupjoin` cannot be translated although it's documened as being supported

I don't understand why this doesn't translate. It seems to be exactly the use case described here.
The LINQ expression
DbSet<A>()
.GroupJoin(
inner: DbSet<B>(),
outerKeySelector: a => a.AId,
innerKeySelector: b => b.AId,
resultSelector: (a, bs) => new {
a = a,
bs = bs
})
produces the error:
could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
The LINQ code producing the exception is
from a in ctx.As
join b in ctx.Bs on a.aId equals b.aId into bs
select new {A = a, Bs = bs.ToList()};
Edit: maybe I misunderstood the doc and this is an example of something that does NOT translate.
Executing a query like the following example generates a result of Blog & IEnumerable. Since databases (especially relational databases) don't have a way to represent a collection of client-side objects, GroupJoin doesn't translate to the server in many cases. It requires you to get all of the data from the server to do GroupJoin without a special selector (first query below). But if the selector is limiting data being selected then fetching all of the data from the server may cause performance issues (second query below). That's why EF Core doesn't translate GroupJoin.
But then my question becomes instead : how do I achieve the result I'm looking for without requiring navigational properties ?
The explanation in the linked documentation just follows the EF Core team vision and is ridiculous, because of course it can easily be translated - I had a long discussion with the team here Query with GroupBy or GroupJoin throws exception #17068 and continue here Query: Support GroupJoin when it is final query operator #19930, trying to convince them why it should be supported, with no luck regardless of the arguments.
The whole point is (and that's the current workaround) it can be processed like if it was correlated subquery (SelectMany), which is translated and processed properly (even though the query result shape has no SQL equivalent.
Anyway, the current status is "Needs Design" (whatever that means), and the workaround is to replace the join with correlated subquery (which is what EF Core is using internally when "expanding" collection navigation properties during the query translation).
In your case, replace
join b in ctx.Bs on a.aId equals b.aId into bs
with
let bs = ctx.Bs.Where(b => a.aId == b.aId)
However, I highly recommend adding and using navigation properties. Not sure why you "can't use" them, in LINQ to Entities which do not project entities they serve just metadata for relationships, thus produce automatically the necessary joins. By not defining them you just put on yourself unneeded limitations (additionally to EF Core limitations/bugs). In general EF Core works better and support more things when using navigation properties instead of manual joins.
Try this query, it should work with EF Core:
var query =
from a in ctx.As
select new {A = a, Bs = ctx.Bs.Where(b => b.Id == a.aId).ToList()};
Probably the .ToList() cannot be translated. Use include instead
var result = ctx.As
.Include(a => a.Bs)
.ToList();
Where you must have a navigation property for the Bs in the A class:
public class A
{
public int aId { get; set; }
public List<B> Bs { get; set; }
}
See:
Eager Loading of Related Data
Relationships - EF Core
EF Core will not allow you to do a GroupJoin without following up with a SelectMany in order to flatten the list. The GroupJoin has no equivalent implementation in SQL, however the GroupJoin/SelectMany is equivalent to an inner-join or left-join (depending on if you use DefaultIfEmpty) so it works fine:
context.Users.GroupJoin(
context.UserRoles,
u => u.UserId,
r => r.UserId,
(user, roles) => new { user, roles })
//Will not work without this line
.SelectMany(x => x.roles.DefaultIfEmpty(), (x, r) => new { x.user, role = r })
.ToList();
If you actually want your results to be grouped (as opposed to trying to do a left-join) you have a few options:
You can materialize the results of a left join, then group the results in-memory (the code below uses my LeftJoin function shown in LEFT OUTER JOIN in LINQ):
context.Users.LeftJoin(
context.UserRoles,
u => u.UserId,
r => r.UserId,
(user, roles) => new { user, roles })
.ToList()
.GroupBy(x => x.user, (u, x) => new
{
User = u,
Roles = x.Select(z => z.role).Where(r => r != null).ToList()
})
.ToList();
You can use a sub-query. Note that EF is smart enough to use a left-join when it generates the SQL:
context.Users.Select(u => new
{
User = u,
Roles = context.UserRoles.Where(r => r.UserId == u.UserId).ToList()
})
.ToList();
If you prefer the GroupJoin syntax, but don't want to have to keep calling all the other functions to flatten, materialize, then re-group the results, you can use my JoinMany() extension method. This method uses the sub-query approach but wraps it in a generic method that looks very similar to the GroupJoin function:
context.Users.JoinMany(
context.UserRoles,
(u, r) => u.UserId == r.UserId,
(user, roles) => new { user, roles })
.ToList();
Supporting code:
public static class QueryableExtensions
{
public static IQueryable<TResult> LeftJoin<TOuter, TInner, TKey, TResult>(
this IQueryable<TOuter> outer,
IEnumerable<TInner> inner, Expression<Func<TOuter, TKey>> outerKeySelector,
Expression<Func<TInner, TKey>> innerKeySelector,
Expression<Func<TOuter, TInner, TResult>> resultSelector)
{
return outer
.GroupJoin(inner, outerKeySelector, innerKeySelector, (o, i) => new { o, i })
.SelectMany(o => o.i.DefaultIfEmpty(), (x, i) => new { x.o, i })
.ApplySelector(x => x.o, x => x.i, resultSelector);
}
public static IQueryable<TResult> JoinMany<TOuter, TInner, TResult>(
this IQueryable<TOuter> outers, IQueryable<TInner> inners,
Expression<Func<TOuter, TInner, bool>> condition,
Expression<Func<TOuter, IEnumerable<TInner>, TResult>> resultSelector)
{
//Use a placeholder "p => true" expression for the sub-query
Expression<Func<TOuter, JoinResult<TOuter, IEnumerable<TInner>>>> joinSelector = o =>
new JoinResult<TOuter, IEnumerable<TInner>> { Outer = o, Inner = inners.Where(p => true) };
//Create the where-clause that will be used for the sub-query
var whereClause = Expression.Lambda<Func<TInner, bool>>(
condition.Body.ReplaceParameter(condition.Parameters[0], joinSelector.Parameters[0]),
condition.Parameters[1]);
//Replace the placeholder expression with our new where clause
joinSelector = Expression.Lambda<Func<TOuter, JoinResult<TOuter, IEnumerable<TInner>>>>(
joinSelector.Body.VisitExpression(node =>
(node is LambdaExpression le && le.Parameters.Count == 1 && le.Parameters[0].Type == typeof(TInner)
&& le.Body is ConstantExpression ce && ce.Value is bool b && b)
? whereClause : null),
joinSelector.Parameters[0]);
return outers.Select(joinSelector).ApplySelector(x => x.Outer, x => x.Inner, resultSelector);
}
private static IQueryable<TResult> ApplySelector<TSource, TOuter, TInner, TResult>(
this IQueryable<TSource> source,
Expression<Func<TSource, TOuter>> outerProperty,
Expression<Func<TSource, TInner>> innerProperty,
Expression<Func<TOuter, TInner, TResult>> resultSelector)
{
var p = Expression.Parameter(typeof(TSource), $"param_{Guid.NewGuid()}".Replace("-", string.Empty));
Expression body = resultSelector?.Body
.ReplaceParameter(resultSelector.Parameters[0], outerProperty.Body.ReplaceParameter(outerProperty.Parameters[0], p))
.ReplaceParameter(resultSelector.Parameters[1], innerProperty.Body.ReplaceParameter(innerProperty.Parameters[0], p));
var selector = Expression.Lambda<Func<TSource, TResult>>(body, p);
return source.Select(selector);
}
public class JoinResult<TOuter, TInner>
{
public TOuter Outer { get; set; }
public TInner Inner { get; set; }
}
}
public static class ExpressionExtensions
{
public static Expression ReplaceParameter(this Expression source, ParameterExpression toReplace, Expression newExpression)
=> new ReplaceParameterExpressionVisitor(toReplace, newExpression).Visit(source);
public static Expression VisitExpression(this Expression source, Func<Expression, Expression> onVisit)
=> new DelegateExpressionVisitor (onVisit).Visit(source);
}
public class DelegateExpressionVisitor : ExpressionVisitor
{
Func<Expression, Expression> OnVisit { get; }
public DelegateExpressionVisitor(Func<Expression, Expression> onVisit)
{
this.OnVisit = onVisit;
}
public override Expression Visit(Expression node)
{
return OnVisit(node) ?? base.Visit(node);
}
}
public class ReplaceParameterExpressionVisitor : ExpressionVisitor
{
public ParameterExpression ToReplace { get; }
public Expression ReplacementExpression { get; }
public ReplaceParameterExpressionVisitor(ParameterExpression toReplace, Expression replacement)
{
this.ToReplace = toReplace;
this.ReplacementExpression = replacement;
}
protected override Expression VisitParameter(ParameterExpression node)
=> (node == ToReplace) ? ReplacementExpression : base.VisitParameter(node);
}

Invoke reactive command repeatedly till a condition is met

I am using ReactiveUI for a UWP app and have two commands CommandA and CommandB. CommandA when invoked attempts to make changes to the hardware. CommandB when invoked reads the hardware and provides the latest value.
I would like to invoke the CommandA (with the parameter as the CombBox value) when a ComboBox value is changed.
After the execution of CommandA I would like to invoke CommandB repeatedly till I get the value that is same as the one selected in ComboBox or if a timeout occurs. On timeout an error should be displayed.
To check that the CommandA is finished executing, I wrote the following code for [1]
this.WhenAnyValue(x => x.ComboBoxAValue)
.InvokeCommand(CommandA);
CommandA.IsExecuting
.Buffer(2,1)
.Where(t => t[0] == true && t[1] == false)
.Select( x=> Unit.Default)
.InvokeCommand(CommandB) // This statement would attempt to invoke CommandB only once
I am not sure how to do [2].
I'm conviced that exists a better solution, but here you have an approach:
public class MyCoolViewModel : ReactiveObject
{
private readonly Subject<Unit> _ticksToInvokeB;
private readonly ObservableAsPropertyHelper<bool> _commandAExecutedCorrectly;
public bool CommandAExecutedCorrectly => _commandAExecutedCorrectly.Value;
public ReactiveCommand<Unit, bool> CommandA { get; set; }
public ReactiveCommand<Unit, bool> CommandB { get; set; }
private string _comboBoxValue;
public string ComboBoxValue
{
get => _comboBoxValue;
set => this.RaiseAndSetIfChanged(ref _comboBoxValue, value);
}
public MyCoolViewModel()
{
//Subject implements IObservable<T> and IObserver<T>, also alow us to tick values to its observable
_ticksToInvokeB = new Subject<Unit>();
CommandA = ReactiveCommand.Create<Unit,bool>( _ =>
{
Console.WriteLine("Command A");
return true;
});
CommandB = ReactiveCommand.CreateFromTask<Unit,bool>( async _ =>
{
await Task.Delay(3000);
var isTheSame = DateTime.Now.Second % 2 == 0;
Console.WriteLine($"CommandB: is the same: {isTheSame}");
if(!isTheSame)//if the value is not the same, tick a new unit, since we ticked a new value, CommandA will be executed
_ticksToInvokeB.OnNext(Unit.Default);
return isTheSame;
});
CommandA//We just send commandA execution to an OAPH
.ToProperty(this, x => x.CommandAExecutedCorrectly, out _commandAExecutedCorrectly);
this.WhenAnyValue(x => x.ComboBoxValue)
.Skip(1) //this is because ComboBoxValue has a initial value (null) so we ignore it
.Select(_ => Unit.Default) //When it changes simply project an Unit
.InvokeCommand(CommandA);//Inke CommandA
this.WhenAnyValue(x => x.CommandAExecutedCorrectly)//When changes maded CommandA will set ChangesMaded to true
.Where(b => b) // only when Command A gets executed correctly
.Do(b => TickUnit()) // Tick a new unit
.Subscribe();
_ticksToInvokeB
.Throttle(TimeSpan.FromMilliseconds(200))//delay a little bit the next value
.InvokeCommand(CommandB);//invokes CommandB
}
private void TickUnit()
{
Console.WriteLine("Ticking new value");
_ticksToInvokeB.OnNext(Unit.Default);
}
}
Let me know if it helps you.
Regards.
First, instead of the buffer technique you used for detecting a completed command, I would do something like this. And instead of worrying about creating a command for CommandB, I would just execute it as a method. You can still use a command if you want, but I'll just be using an async call in this example. I'm using ExecuteUntilItYieldsTheSelectedComboBoxValue to continuously execute your CommandB logic in a loop until a matching value is found. It utilizes Observable.Create so you can control when OnNext is triggered. And you can tag on a Timeout to it and handle it in the Subscribe extension.
CommandA.IsExecuting
// IsExecuting has an initial value of false. We can skip that first value
.Skip(1)
// Filter until the executing state becomes false.
.Where(isExecuting => !isExecuting)
// Start an inner observable for your "CommandB" logic.
.Select(_ => ExecuteUntilItYieldsTheSelectedComboBoxValue())
// Whenever CommandA is invoked, dispose of the last inner observable subscription and resubscribe.
.Switch()
.Subscribe(
_ => Console.WriteLine("OnNext"),
ex => [display error message]);
...
private IObservable<Unit> ExecuteUntilItYieldsTheSelectedComboBoxValue()
{
return Observable
.Create<Unit>(
async o =>
{
int randNum = -1;
do
{
randNum = await GetRandomNumberAsync();
} while(randNum != ComboBoxValue);
o.OnNext(Unit.Default);
o.OnCompleted();
return Disposable.Empty;
})
.Timeout(TimeSpan.FromSeconds(3));
}
Update
Based on what Enigmativity pointed out, about needing to return something better than Disposable.Empty (to cancel any in-progress async task and break out of the loop), I'm changing the ExecuteUntilItYieldsTheSelectedComboBoxValue method to be the following:
private IObservable<Unit> ExecuteUntilItYieldsTheSelectedComboBoxValue()
{
return Observable
// Call our async method and pass in a cancellation token.
.FromAsync(ct => GetRandomNumberAsync(ct))
// Keep generating random numbers.
.Repeat()
// Until we find one that matches the ComboBoxValue.
.Where(x => x == ComboBoxValue)
// Just take the first one so this inner observable will complete.
.Take(1)
.Select(_ => Unit.Default)
.Timeout(TimeSpan.FromSeconds(3));
}
Note that it's still possible to make the Observable.Create method work correctly, but this edited solution is cleaner and less error prone. Let me know if you have any questions.

How do I reuse an object instance in an Observable chain?

In rx, how do you handle the need to reuse an object instance in one step in the next step? For example, I need to get a context in the ORM to then act upon. Async/Await is in the syntax below:
public async Task<IList<string>> Delete(IList<string> ids)
{
var context = await _contextFactory.CreateContext();
context.Set<T>().RemoveRange(
context.Set<T>().Where(item => ids.Contains(item.Id)));
return ids;
}
An Observable version is
public IObservable<string> DeleteObservable(IList<string> ids)
{
return ids.ToObservable()
.Select(i =>
{
var context = await _contextFactory.CreateContext();
context.Set<T>().RemoveRange(
context.Set<T>().Where(item => item.Id == id));
return id;
});
}
However, I don't want to create a new context every time I delete an item. I want to create a context and then reuse it in the select. How should I do that?
Yes, in this example it would be best to also buffer and submit the ids together, but this was just an example for my question. I hope that part is not distracting.
The more idiomatic way of doing it is like this:
public IObservable<string> DeleteObservable(IList<string> ids)
{
return Observable.Using(
async () => await _contextFactory.CreateContext(),
context =>
ids.ToObservable().Select(i =>
{
context.Set<T>().RemoveRange(context.Set<T>().Where(item => item.Id == i));
return i;
}));
}
The Observable.Using method creates a disposable resource that gets disposed when the subscription to the observable closes.
The only problem with this is that the statement context.Set<T>().RemoveRange(context.Set<T>().Where(item => item.Id == i)); just shouldn't be inside an observable like that. Rx is about queries. Any changes should be made in a .Subscribe method.
What are you trying to achieve?
I think I got it and the answer keeps ended up being 'SelectMany'. I guess I'm still getting used to these operators.
public IObservable<string> DeleteObservable(IList<string> ids)
{
return Observable
.Return(_contextFactory)
.SelectMany(factory => factory.CreateContext())
.Zip(ids.ToObservable(), (dbContext, entityId) =>
{
dbContext.Set<T>().RemoveRange(
dbContext.Set<T>().Where(item => item.Id == entityId));
return entityId;
});
}

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.01

This is function that takes two List<int> and update corresponding tables at database. When I run both functions using threads T1 and T2 , then it shows me exception at the second foreach loop:
"The ObjectContext instance has been disposed and can no longer be
used"
I already used query like
var res = ctx.EmailDBs.Include(x => x.EmailDBid == id);
but it's not working.
Please share something to persist the ctx connection until both methods are executed.
public static void UpdateEmail(List<int> invalidEmailToUpdate, List<int> validEmailToUpdate)
{
using (OnliveMTAEntities ctx = new OnliveMTAEntities())
{
Thread T1, T2;
T1 = new Thread(() =>
{
foreach (int id in invalidEmailToUpdate)
{
var res = ctx.EmailDBs.FirstOrDefault(x => x.EmailDBid == id);
res.Status = 6;
}
});
T1.Start();
Thread.Sleep(100);
T2 = new Thread(() =>
{
foreach (int id in validEmailToUpdate)
{
var res = ctx.EmailDBs.FirstOrDefault(x => x.EmailDBid == id);
res.Status = 7;
}
});
T2.Start();
ctx.SaveChanges();
}
}
You need to wait until both threads T1 and T2 are fully completed. Only then you can save dataContext ctx.SaveChanges();
For that purpose is method called Join() (MSDN). Use it like that:
// previous code here
T2.Start();
// wait for threads to be done
T1.Join();
T2.Join();
// now both of them are done
ctx.SaveChanges();
// end of using(...) and other code
EDIT: I forgot to mention: using both Join(), you can get rid of Thread.Sleep(100);. I believe that this is the reason why you got error on second thread. That call will pause execution of current thread (which will start T2) for 100ms and during that time T1 succeded to complete it's work.

How to do I show progress when using Reactive Extensions in C#

Am using reactive extensions in C# to perform some calculations. Here is how my code looks like so far. I have tried to wrap the code around so that I can show progress while to executing a series of tasks within my Calculate method
Here is the observable
IObservable<ResultWithProgress<SampleResult>> Calculate(){
return Observable.Create<ResultWithProgress<SampleResult>>(obs => {
var someTask = DoSomeTask1();
obs.OnNext(new ResultWithProgress(){Progress = 25, ProgressText ="Completed Task1"});
var someOtherTask = DoSomeMoreTask();
obs.OnNext(new ResultWithProgress(){Progress = 50, ProgressText ="Completed Task2"});
var calcResult = DoSomeMoreTask2();
obs.OnNext(new ResultWithProgress(){Progress = 75, ProgressText = "Completed Task3"});
var calcResult = FinalCalc();
obs.OnNext(new ResultWithProgress(){Progress = 100, ProgressText ="Completed Task4", Result = calcResult});
obs.OnCompleted();
}
}
Result Class wrapping progress and result
class ResultWithProgress<T>{
public int Progress {get; set;}
public Result T {get; set;}
public string ProgressText {get; set;}
}
Result object which contains the final result
class SampleResult{}
Usage:
Calculate().Subscribe(resultWithProgress => {
if(resultWithProgress.Result == null) //Show progress using resultWithProgress.Progress
else // get the result
})
I somehow feel that this might not the best way to do it. It feels that creating ResultWithProgress object many times without the Result seems like a code smell, especially if I have more than 10 tasks that I want to do within my Calculate()
I would appreciate it if you can give me any pointers on how to use this or am I approaching this problem wrongly?
This answer uses the same principles Enigmativity's answer discusses.
This version uses the async overload of Create.
It also makes use of the .NET 4.5 IProgress instead of a raw Action<T> to report progress.
struct CalculationProgress
{
public int Progress { get; private set; }
public string ProgressText { get; private set; }
public CalculationProgress(int progress, string progressText)
: this()
{
Progress = progress;
ProgressText = progressText;
}
}
public IObservable<Result> Calculate(IProgress<CalculationProgress> progress)
{
return Observable.Create<Result>((observer, cancellationToken) =>
{
// run the work on a background thread
// so we do not block the subscriber
// and thus the subscriber has a chance
// to unsubscribe (and cancel the work if desired)
return Task.Run(() =>
{
DoSomeTask1();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(25, "First task"));
DoSomeTask2();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(50, "Second task"));
DoSomeTask3();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(75, "third task"));
var result = DoFinalCalculation();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(100, "final task"));
observer.OnNext(result);
}, cancellationToken);
});
}
It took me some time to actually get your code to run. There were numerous syntax errors, but most importantly your Observable.Create did not have a return value.
Observable.Create should create an observable that the obs variable subscribes to and you return that IDisposable. That's so a subscriber can terminate the observable before it has completed.
Your observable directly interacts with the obs and finally calls obs.OnComplete() before the Observable.Create is completed. This means that there is no opportunity for the calling subscriber to terminate the computation because it has completed before the subscription has finished!
What you need is a way to build an observable within the Observable.Create to make it behave properly.
Now, since you are trying to return progress during your computation you are expecting side-effects. So it is easier to inject state at the beginning and just have a pure observable otherwise.
Here's how I might go about doing this.
First I change the signature of Calculate to become:
IObservable<string> Calculate(Action<ResultWithProgress<string>> progress)
Now I am injecting an action that I can use to report on my progress.
Here's how the call to Calculate might look:
Calculate(rwp => Console.WriteLine(rwp)).Subscribe(result => { });
Now here's the full Calculate method:
public IObservable<string> Calculate(Action<ResultWithProgress<string>> progress)
{
return Observable.Create<string>(obs =>
{
// This action just removes duplication from the query below
// and has the purpose of safely calling `progress`
Action<int, string, string> report = (pv, r, pt) =>
{
var p = progress;
if (p != null)
{
p(new ResultWithProgress<string>()
{
Progress = pv,
Result = r,
ProgressText = pt,
});
}
};
var query =
from someTask in Observable.Start(() => DoSomeTask1())
.Do(x => report(25, x, "Completed Task1"))
from someOtherTask in Observable.Start(() => DoSomeMoreTask())
.Do(x => report(50, x, "Completed Task2"))
from calcResultX in Observable.Start(() => DoSomeMoreTask2())
.Do(x => report(75, x, "Completed Task3"))
from calcResult in Observable.Start(() => DoSomeTask1())
.Do(x => report(100, x, "Completed Task4"))
select calcResult;
return query.Subscribe(obs);
});
}