是否存在将项添加到ReactiveAsyncCommand中的ObservableCollection或是否必须使用Dispather的方法?什么是RxUI处理这种情况的方式?
编辑:当LoadData正在运行时,这些项目应逐个加载到集合中。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MaxRows = 100;
Translations = new ReactiveCollection<string>();
LoadDataCommand = new ReactiveAsyncCommand();
LoadDataCommand.RegisterAsyncAction(_ => LoadData());
InitializeComponent();
this.DataContext = this;
}
private void LoadData()
{
for (int i = 1; i < MaxRows; ++i)
{
Thread.Sleep(100);
// What's the RxUI Way for this?
this.Dispatcher.Invoke(() => Translations.Add(i.ToString()));
}
}
public int MaxRows { get; set; }
public ReactiveCollection<string> Translations { get; set; }
public ReactiveAsyncCommand LoadDataCommand { get; set; }
}
答案 0 :(得分:1)
放手一搏:
public MainWindow()
{
InitializeComponent();
MaxRows = 100;
Translations = new ReactiveCollection<string>();
LoadDataCommand = new ReactiveAsyncCommand();
LoadDataCommand.RegisterAsyncFunction(_ => LoadData())
.Subscribe(items =>
{
foreach(var i in items) Translations.Add(i);
})
LoadDataCommand.ThrownExceptions.Subscribe(ex =>
{
Console.WriteLine("Oh crap: {0}", ex);
})
InitializeComponent();
this.DataContext = this;
}
private List<int> LoadData()
{
// TODO: Return the list of stuff you want to add
return Enumerable.Range(0, maxRows).ToList();
}
这个想法是,LoadData将在后台线程上调用,你可以在那里做任何你想做的事情,阻止网络调用,读取文件等。但是,RegisterAsync *的订阅是保证在UI线程上运行。方便!
注意,我还添加了ThrownExceptions订阅 - 这很重要,否则如果LoadData失败,您的RegisterAsync *调用将停止工作。
编辑:好的,现在你有点花哨了。虽然我在讨论像这样的结果流式传输的UI的实用程序(尝试在不断移动的ListBox中选择内容令人沮丧),但我们仍然这样做 - 首先,将LoadData
更改为流式传输结果:
private IObservable<int> LoadData()
{
var ret = new Subject<int>();
// Run something in the background
Observable.Start(() =>
{
try
{
for(int i=0; i < 100; i++)
{
// TODO: Replace with streaming items
ret.OnNext(10);
Thread.Sleep(100);
}
ret.OnCompleted();
}
catch (Exception ex)
{
ret.OnError(ex);
}
}, RxApp.TaskpoolScheduler)
return ret;
}
然后,您所做的只是在命令上更改几行:
// Now it's RegisterAsyncObservable instead
LoadDataCommand.RegisterAsyncObservable(_ => LoadData())
.Subscribe(item =>
{
Translations.Add(item);
})
请注意,这不是很强大的功能™,但我想给你一些容易开始的东西。