How to make ReactiveCommand Async ?

2019-08-10 08:02发布

I am using ReactiveCommand to get Async behavior. According to Paul Betts comment in this discussion

If you're using RxUI 5.0, just use ReactiveCommand, they are now merged and have a better API.

I have the following code to test to see if it does the Async behavior. And it turns out to be not. It freezes up the UI for 5 seconds.

MyReactiveCommand.Subscribe(s =>
{   
    Thread.Sleep(5000);
});

What am I missing?

标签: reactiveui
3条回答
欢心
2楼-- · 2019-08-10 08:55

I'm new to ReactiveUI, but I believe the async and not freezing the UI are different issues. Async can happen on 1 thread, ie it doesn't wait for some result, but can continue processing other things. I think if you make the thread sleep and you only have 1 thread, then it won't be able to do any other work.

Something like Task.Delay I believe will let you wait for some time without blocking the thread.

If you want to use multiple threads, you can use the thread pool as you provided in your answer, but to run the subscription implementation on a thread pool thread I believe it should be:

.SubscribeOn(RxApp.TaskPoolScheduler)

Then if you want to do something with the UI needing thread affinity, you need to move back onto the UI thread with:

.ObserveOn(RxApp.MainThreadScheduler)

ObserveOn is where your IObserverable methods OnNext/OnComplete/OnError context is and SubscribeOn is where the subscribe implementation context is.

查看更多
来,给爷笑一个
3楼-- · 2019-08-10 08:58

Try:

MyReactiveCommand
.RegisterAsyncAction(_ =>
                         {
                           Thread.Sleep(5000);
                         });

And if you need to return a result:

MyReactiveCommand
.RegisterAsyncFunction(o =>
                          {   
                            Thread.Sleep(5000);
                            return o.ToString();
                          })
.Subscribe(s => MessageBox.Show(string.Format("{0} was returned", s)));
查看更多
Luminary・发光体
4楼-- · 2019-08-10 09:01

I fixed it by using TaskPoolScheduler. Not sure if this is how it is meant to be.

MyReactiveCommand
.ObserveOn(RxApp.TaskPoolScheduler)
.Subscribe(s =>
{   
    Thread.Sleep(5000);
});
查看更多
登录 后发表回答