I have this code from old examples (Reactive UI 4):
StartAsyncCommand = new ReactiveCommand();
StartAsyncCommand.RegisterAsyncAction(_ =>
{
Progress = 0;
var exe = Enumerable.Range(0, 10).Select(x =>
{
Thread.Sleep(100);
return x;
}).ToObservable();
exe.Subscribe(x =>Progress += 10);
});
It works fine, UI does not block and button is disable until Progress gets 100%.
When I migrate to version 6, I tried many ways to achieve same functionality without success.
These are my attempts:
1) Using CreateAsyncObservable
GenerateCommand = ReactiveCommand.CreateAsyncObservable(canGenerate, x => DoSomething());
public IObservable<Unit> DoSomething()
{
var exe = Enumerable.Range(0, 10).Select(
x =>
{
Thread.Sleep(200);
return x;
}).ToObservable().ObserveOnDispatcher().SubscribeOn(NewThreadScheduler.Default);
exe.Subscribe(x =>
Progress += 10
);
return Observable.Return(new Unit());
}
It works but button does not disable.
2) With CreateAsyncTask
GenerateCommand = ReactiveCommand.CreateAsyncTask(canGenerate, x => DoSomething());
public async Task<Unit> DoSomething()
{
var exe = Enumerable.Range(0, 10).Select(
x =>
{
Thread.Sleep(200);
return x;
}).ToObservable().ObserveOnDispatcher().SubscribeOn(NewThreadScheduler.Default);
await exe;
exe.Subscribe(x =>
Progress+=10
);
return new Unit();
}
It works but button only disable until await ends.
3) Based on ReactiveUI 6 Async Command Not Running on Background Thread in WPF app
GenerateCommand = ReactiveCommand.CreateAsyncTask(canGenerate, x => DoSomething());
public async Task<Unit> DoSomething()
{
var execTask = Task.Factory.StartNew(() =>
{
var exe = Enumerable.Range(0, 10).Select(
x =>
{
Thread.Sleep(200);
return x;
}).ToObservable();
exe.Subscribe(x =>
Progress += 10
);
return new Unit();
});
return execTask.Result;
}
This throws an exception.
UPDATE
4) Subscribe
command:
GenerateCommand = ReactiveCommand.CreateAsyncObservable(canGenerate, x => DoSomething());
GenerateCommand.ObserveOnDispatcher().SubscribeOn(NewThreadScheduler.Default)
.Subscribe(x => Progress += 10);
public IObservable<int> DoSomething()
{
return = Observable.Range(0, 10).Select(
x =>
{
Thread.Sleep(200);
return x;
});
}
Same result...
How could I achieve same functionality with version 6?
What am I doing wrong?