ReactiveUI:来自后台线程的 UI 线程上的计划任务
ReactiveUI: Scheudle task on UI thread from background thread
我需要在后台线程上处理大型数据集,然后在 WPF 界面的 DataGrid 控件中显示该数据。数据来自外部工业设备,为此我提供了第三方库。因此,我从该库的委托中获取数据。
我的问题是我似乎无法从后台线程安排对 MainUI 线程的操作,我不确定如何解决这个问题。
数据视图模型:
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);
}
数据得到处理...
public void HandleData()
{
ImpactorResultData result;
... Processing ...
// NOW I TRY TO UPDATE THE COLLECTIONS FROM THE MAIN UI THREAD
Observable.Start(
() => UpdateUiThreadCollections(result),
RxApp.MainThreadScheduler
);
}
我更新了 DataViewModel 的实例。我希望,因为我安排了在 UI 线程(上面)上执行的操作,所以一切都会顺利进行。相反,我得到一个异常,绑定到 DataGrid 的集合必须在主 UI 线程中更新。
/// <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);
});
}
出于某种原因,两者:
Observable.Start(
() => UpdateUiThreadCollections(result),
RxApp.MainThreadScheduler
);
RxApp.MainThreadScheduler.Schedule(() =>
{
UpdateUiThreadCollections(result);
});
仍在后台线程上安排操作。关于 ReactiveUI 或 Reactive Extensions,肯定有一些我不理解的地方。
提前感谢您的任何见解。
您应该能够从后台线程更新您的 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 包。
我需要在后台线程上处理大型数据集,然后在 WPF 界面的 DataGrid 控件中显示该数据。数据来自外部工业设备,为此我提供了第三方库。因此,我从该库的委托中获取数据。
我的问题是我似乎无法从后台线程安排对 MainUI 线程的操作,我不确定如何解决这个问题。
数据视图模型:
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);
}
数据得到处理...
public void HandleData()
{
ImpactorResultData result;
... Processing ...
// NOW I TRY TO UPDATE THE COLLECTIONS FROM THE MAIN UI THREAD
Observable.Start(
() => UpdateUiThreadCollections(result),
RxApp.MainThreadScheduler
);
}
我更新了 DataViewModel 的实例。我希望,因为我安排了在 UI 线程(上面)上执行的操作,所以一切都会顺利进行。相反,我得到一个异常,绑定到 DataGrid 的集合必须在主 UI 线程中更新。
/// <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);
});
}
出于某种原因,两者:
Observable.Start(
() => UpdateUiThreadCollections(result),
RxApp.MainThreadScheduler
);
RxApp.MainThreadScheduler.Schedule(() =>
{
UpdateUiThreadCollections(result);
});
仍在后台线程上安排操作。关于 ReactiveUI 或 Reactive Extensions,肯定有一些我不理解的地方。
提前感谢您的任何见解。
您应该能够从后台线程更新您的 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 包。