我需要在后台线程上处理大量数据,然后在WPF界面的DataGrid控件中显示该数据。数据来自外部工业设备,为此我提供了一个第三方库。因此,我从该库的委托中获取数据。
我的问题是我似乎无法从后台线程安排对MainUI线程的操作,而且我不确定如何解决此问题。
数据视图模型:
sudo cp -r /usr/lib/swift/*.dylib /Applications/Xcode.app/Contents/Frameworks
sudo touch /Applications/Xcode.app/Contents/Frameworks/.swift-5-staged
第三方库委托发送数据。
public class DataViewModel : ReactiveObject
{
public SourceList<SummaryData> SummaryData = new SourceList<SummaryData>();
public ReadOnlyObservableCollection<SummaryData> SummaryDataView;
public SourceList<EnergyTable> SampleData = new SourceList<EnergyTable>();
public ReadOnlyObservableCollection<EnergyTable> SampleDataView;
public DataViewModel()
{
SummaryData.Connect()
.Bind(out SummaryDataView)
.Subscribe();
SampleData.Connect()
.Bind(out SampleDataView)
.Subscribe();
}
}
数据得到处理...
protected void OnSqlCommandCode(Tag tag)
{
// Process the
Observable.Start(
() => HandleData(),
RxApp.TaskpoolScheduler)
.ObserveOn(RxApp.MainThreadScheduler);
}
我更新DataViewModel的实例。我希望,由于我安排了要在UI线程上执行的操作(上述),因此一切都会顺利进行。取而代之的是,我得到一个例外,即与DataGrid绑定的集合必须在主UI线程中进行更新。
public void HandleData()
{
ImpactorResultData result;
... Processing ...
// NOW I TRY TO UPDATE THE COLLECTIONS FROM THE MAIN UI THREAD
Observable.Start(
() => UpdateUiThreadCollections(result),
RxApp.MainThreadScheduler
);
}
由于某些原因,两者:
/// <summary>
/// Collections tied to data linked to a UI control need to be called from the
/// UI thread.
///
/// The other option is to remake the ObservableRangeCollection every time
/// from the list.
/// </summary>
protected static void UpdateUiThreadCollections(
ImpactorResultData result
)
{
dataViewModel.SummaryData.Add(result.SummaryData);
dataViewModel.SampleData.Edit(innerList =>
{
innerList.Clear();
innerList.AddRange(result.Samples);
});
}
仍在后台线程上调度操作。关于ReactiveUI或Reactive Extensions,肯定有一些我不了解的地方。
预先感谢您提供任何见解。
答案 0 :(得分:0)
您应该能够从后台线程更新SourceList
。您不需要所有复杂的逻辑。相反,在绑定到UI实际使用的属性之前,请使用System.Reactive.Linq
和ObserveOn()
扩展名。
在您的视图模型中:
SummaryData.Connect()
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out SummaryDataView)
.Subscribe();
SampleData.Connect()
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out SampleDataView)
.Subscribe();
哦,我不是Wpf用户,但我记得还有一些专门用于Wpf的ReactiveUI软件包。