问题
Just dabbling with RxUI and trying to get a noddy example to work...
I've got a WPF view with a ListBox and a button. When I press the button (Go) I want to run a method on a background thread and have the results it produces be added to the ListBox. I'm logging the thread id to check what's executing where. The problem is I always see all the operations happening on the same thread. I've tried specifying Scheduler.Default on the CreateAsyncObservable but then nothing gets added to the ListBox.
public class MainViewModel : ReactiveObject
{
public MainViewModel()
{
Results = new ReactiveList<string>();
var seq = ReactiveCommand.CreateAsyncObservable(_ => GetAsyncResults());
seq.ObserveOn(Scheduler.CurrentThread);
seq.Subscribe(s =>
{
Results.Add(string.Format("{0} thread {1}", s, Thread.CurrentThread.ManagedThreadId));
});
Results.Add(string.Format("main thread {0}", Thread.CurrentThread.ManagedThreadId));
Go = ReactiveCommand.Create();
Go.Subscribe(_ => seq.Execute(null));
}
public static IObservable<string> GetAsyncResults()
{
Thread.Sleep(1000);
return (new[] {"Rod", "Jane", "Freddy"}).ToObservable();
}
private readonly ObservableAsPropertyHelper<List<string>> _strings;
public List<string> Strings {get { return _strings.Value; }}
public ReactiveCommand<object> Go { get; protected set; }
public ReactiveList<string> Results { get; set; }
}
回答1:
Rx doesn't switch threads until you ask it, and GetAsyncResults simply returns a list of items synchronously. You need to specify RxApp.TaskpoolScheduler
to move stuff to a background thread.
public static IObservable<string> GetAsyncResults()
{
return (new[] {"Rod", "Jane", "Freddy"}).ToObservable(RxApp.TaskpoolScheduler);
}
seq.ObserveOn(Scheduler.CurrentThread);
You didn't use the return value of this, so it doesn't do anything
Go = ReactiveCommand.Create();
Why are you creating two separate commands here?
来源:https://stackoverflow.com/questions/25123992/reactiveui-cant-get-code-to-run-on-background-thread