如何将ServiceStack.GetAsync与ReactiveCommand一起使用(v6)

时间:2015-03-03 21:26:25

标签: c# servicestack async-await reactiveui

我正在尝试将ReactiveCommandServiceStack asynchronous API结合起来。

永远不会调用x => _reactiveList.AddRange(x),并且测试res为空。我现在不知道如何将ServiceStack的Task<TResponse> GetAsync<TResponse>(IReturn<TResponse> requestDto)结果转换为反应IObservable<T>

    public ReactiveCommand<IList<string>> ServiceReadCommand { get; protected set; }

    public ReactiveList<string> ReactiveList
    {
        get { return _reactiveList; }
        set { _reactiveList = this.RaiseAndSetIfChanged(ref _reactiveList, value); }
    }

    private ReactiveList<string> _reactiveList = new ReactiveList<string>();

    public TestViewModel(IScreen screen = null)
    {
        HostScreen = screen;

        ServiceReadCommand = ReactiveCommand.CreateAsyncTask(x => ServiceCommandTask(), RxApp.TaskpoolScheduler);
        ServiceReadCommand.ThrownExceptions.Subscribe(x => Console.WriteLine((object)x));
        ServiceReadCommand.Subscribe(x => _reactiveList.AddRange(x));
    }

    private async Task<IList<string>> ServiceCommandTask()
    {
        this.Log().Info("Service command task");

        var baseUri = "http://localhost:9010";
        var client = new JsonServiceClient(baseUri);

        // Works
        return await Observable.Return(new List<string> { "" });

        // Don't
        return await client.GetAsync(new TestRequest());
    }

测试方法:

    [TestMethod]
    public void TestMethod1()
    {
        IList<string> res = null;
        new TestScheduler().With(sched =>
        {
            var viewModel = new TestViewModel();

            viewModel.ServiceReadCommand.CanExecute(null).Should().BeTrue();
            viewModel.ServiceReadCommand.ExecuteAsync(null).Subscribe(x => res = x);

            sched.AdvanceByMs(1000);

            return viewModel.ReactiveList;
        });

        res.Should().NotBeEmpty();
    }

我添加了console application所有代码。将ServiceCommandTask更改为IObservable<T>没有帮助。在

之间添加Thread.Sleep()
viewModel.ServiceReadCommand.ExecuteAsync(null).Subscribe(x => res = x);
//Thread.Sleep(1000);
sched.AdvanceByMs(1000);

解决了这个问题,但这不是一个选择。

2 个答案:

答案 0 :(得分:1)

好的,有几件事可能是错的。一切看起来都应该运行,但你永远不知道。

我知道在直接处理任务和TestScheduler时ReactiveUI中通常会有一些奇怪的东西,所以你可以在这方面尝试一些事情。

  1. 您可以使用ToObservable() extension methodTask<TResponse>转换为IObservable<TResponse>

    using System.Reactive.Linq;
    // ...
    return await (client.GetAsync(new TestRequest()).ToObservable());
    
  2. 另一个想法是强制您的ServiceCommandTask()方法返回IObservable而不是async/await。要做到这一点,您必须更改创建ReactiveCommand以使用ReactiveCommand.CreateAsyncObservable的方式,并且只需在ServiceCommandTask()的{​​{1}}上使用ToObservable()来自ServiceStack的电话。

  3. Task转换为Task的原因可能是有效的,因为IObservable依赖虚拟时间等待事情发生。 TestScheduler无法与TestSchedluer正确互动,因此当它“提前”跳过1秒时,现实世界中没有真正的时间。如果ServiceStack调用没有立即返回,那么我希望情况就是这样,上述解决方案可能会或可能无法解决该问题。

答案 1 :(得分:0)

您正在ReactiveUI端做正确的事情,而ServiceStack正在进行一些事情。