我对Rx.Net和动态数据很陌生,现在通过使用这些反应性UI扩展,我面临着以下问题。
我所努力达到的目标:
TaskpoolScheduler上应用动态的数据Filter操作(或者通常从后台线程将传入的数据Filter数据过滤到SourceList
但是,当SourceList被来自不同任务的数据填充时,我会得到'System.NotSupportedException' in System.Reactive.dll错误。所以我得用调度员线程。
怎么解决这个问题?
一个最低限度的工作示例:
using DynamicData;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ReactiveExtensionsTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly ReadOnlyObservableCollection<DataModel> _items;
public ReadOnlyObservableCollection<DataModel> Items => _items;
public MainWindow()
{
InitializeComponent();
DataContext = this;
var bgDataService = new BackroundDataService();
bgDataService
.Connect()
.ObserveOn(RxApp.TaskpoolScheduler)
.Filter(x => x.IntA % 2 == 0)
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out _items)
.Subscribe();
}
}
class BackroundDataService : IBackgroundDataService
{
private readonly SourceList<DataModel> _data = new SourceList<DataModel>();
public IObservable<IChangeSet<DataModel>> Connect() => _data.Connect();
public BackroundDataService()
{
Task.Factory.StartNew(async () =>
{
int length = 100_000;
for (int i = 0; i < length; i++)
{
_data.Add(new DataModel { IntA = i, StringB = "B {i}" });
await Task.Delay(200);
}
});
}
}
internal interface IBackgroundDataService
{
IObservable<IChangeSet<DataModel>> Connect();
}
public class DataModel
{
public int IntA { get; set; }
public string StringB { get; set; }
}
}Items属性绑定到ListBox,如下所示
发布于 2020-06-24 13:03:03
你试过吗
var bgDataService = new BackroundDataService();
bgDataService
.Connect()
.ObserveOn(RxApp.TaskpoolScheduler)
.Filter(x => x.IntA % 2 == 0)
.Bind(out _items)
.SubscribeOn(RxApp.MainThreadScheduler);也许值得一试。
发布于 2020-06-25 18:08:00
另一种可能的解决办法如下:
var bgDataService = new BackroundDataService();
bgDataService
.Connect()
.ObserveOn(RxApp.TaskpoolScheduler)
.Filter(x =>
{
Thread currentThread = Thread.CurrentThread;
Console.WriteLine($"Applied filter on thread: {currentThread.GetApartmentState()} with Id: "
+ $"{currentThread.ManagedThreadId} and is background: {currentThread.IsBackground} and from thread pool: {currentThread.IsThreadPoolThread}");
return x.IntA % 2 == 0;
})
.ObserveOnDispatcher()
.Bind(out _items)
.Subscribe(x =>
{
Thread currentThread = Thread.CurrentThread;
Console.WriteLine($"Subscribption runs on thread: {currentThread.GetApartmentState()} with Id: "
+ $"{currentThread.ManagedThreadId} and is background: {currentThread.IsBackground} and from thread pool: {currentThread.IsThreadPoolThread}");
});https://stackoverflow.com/questions/62542554
复制相似问题