我正在尝试将ReactiveCommand
与ServiceStack 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);
解决了这个问题,但这不是一个选择。
答案 0 :(得分:1)
好的,有几件事可能是错的。一切看起来都应该运行,但你永远不知道。
我知道在直接处理任务和TestScheduler
时ReactiveUI中通常会有一些奇怪的东西,所以你可以在这方面尝试一些事情。
您可以使用ToObservable()
extension method将Task<TResponse>
转换为IObservable<TResponse>
。
using System.Reactive.Linq;
// ...
return await (client.GetAsync(new TestRequest()).ToObservable());
另一个想法是强制您的ServiceCommandTask()
方法返回IObservable
而不是async/await
。要做到这一点,您必须更改创建ReactiveCommand
以使用ReactiveCommand.CreateAsyncObservable
的方式,并且只需在ServiceCommandTask()
的{{1}}上使用ToObservable()
来自ServiceStack的电话。
将Task
转换为Task
的原因可能是有效的,因为IObservable
依赖虚拟时间等待事情发生。 TestScheduler
无法与TestSchedluer
正确互动,因此当它“提前”跳过1秒时,现实世界中没有真正的时间。如果ServiceStack调用没有立即返回,那么我希望情况就是这样,上述解决方案可能会或可能无法解决该问题。
答案 1 :(得分:0)
您正在ReactiveUI端做正确的事情,而ServiceStack正在进行一些事情。