gpt4 book ai didi

c# - 如何在后台获取数据并在准备好时用数据异步更新 UI?

转载 作者:行者123 更新时间:2023-11-30 21:38:03 30 4
gpt4 key购买 nike

我有 Selected 对象 DataGrid,其行选择更改在方法中处理(使用交互事件触发器 InvokeCommandAction)。一行代表现实生活中的对象并具有许多属性。

我首先设置行对应的属性并在 map 上突出显示对象,做一些其他事情,最后调用异步方法获取对象属性并使用这些属性刷新属性 DataGrid。

SelectedObjectsViewModel.cs(包含 SelectedObjects DataGrid 的 UserControl 的 View 模型)

public void SelectedObjectsGridSelectionChangedCommand(object parameter)
{
IList selectedRows = parameter as IList;
if (selectedRows.Count == 1)
ObjectProperties.Instance.SetAttributeObjectNoRefresh(((SelectedNetObjectBindingSource)selectedRows[0]).Data);
else
ObjectProperties.Instance.SetAttributeObjectNoRefresh(null);

SetAttributeObjectExtraHightlight<SelectedNetObjectBindingSource>(selectedRows);

DoSomeOtherStuff(selectedRows)

App.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
{
((ObjectViewModel)MyApp.ViewModels["Shared.Panels.Object"]).SelectedObjectsChanged();
}));
}

ObjectViewModel.cs(包含属性 DataGrid 的 UserControl 的 View 模型)

    // this is ItemsSource binding for properties datagrid 
public ICollectionView ObjectInfoItems { get; private set; }

public ObjectViewModel()
{
ObjectInfoItems = CollectionViewSource.GetDefaultView(ObjectProperties.Instance.GetAttributeObjectAttributes());
}

public void SelectedObjectsChanged()
{
// refreshed DataGrid
ObjectInfoItems.Refresh();
}

对象属性.cs

    public void SetAttributeObjectNoRefresh(NetObject netObject)
{
_attributeObject = netObject;
}

public IEnumerable<PropertyRow> GetAttributeObjectAttributes()
{
if (_attributeObject != null)
{
List<string> fieldNames = new List<string>();
List<string> visibleNames = new List<string>();
List<string> values = new List<string>();
/* get properties for _attributeObject from db and
* process in native code */
var properties = GetPropertiesFilterAndSort(fieldNames, visibleNames, values, _attributeObject);

foreach (var property in properties)
{
yield return property;
}
}
}

但是,在完成所有其他操作(如突出显示)后,包含要刷新的对象属性的 DataGrid 最多有 1.2 秒的延迟。我想立即开始获取我知道的对象,继续突出显示等,最后异步启动 SelectedObjectsChanged 以使用获取的属性数据来刷新 DataGrid。

抓取涉及数据库抓取和一些处理。根据环境和设置,数据库提取时间可能高达 80%,但也可能只有 50%。

我的问题是:应该怎么做才能:

  1. Selected 对象 DataGrid 中的行选择和 map 上的突出显示立即进行,根本不等待属性获取或属性数据网格刷新
  2. 在 Selected objects datagrid 选择之后属性 DataGrid 刷新不会有很长时间的延迟,因为它正在获取属性

谢谢!

最佳答案

您应该在后台线程上执行任何长时间运行的方法。请注意,您不能在后台线程上访问任何 UI 元素,因此您基本上需要启动一个新任务来获取数据,然后在任务完成后处理任何 UI 内容。

这是一个在后台线程上执行 GetAttributeObjectAttributes() 方法的基本示例:

private ICollectionView _ojectInfoItems;
public ICollectionView ObjectInfoItems
{
get { return myVar; }
set { myVar = value; OnPropertyChanged(); }
}

public ObjectViewModel()
{
Task.Factory.StartNew(() =>
{
return ObjectProperties.Instance.GetAttributeObjectAttributes();
}).ContinueWith(task =>
{
ObjectInfoItems = CollectionViewSource.GetDefaultView(task.Result);
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}

注意 ObjectViewModel 类应该实现 INotifyPropertyChanged接口(interface)并在设置数据绑定(bind) ObjectInfoItems 属性时引发 PropertyChanged 事件。

编辑:

基于您的评论的另一个示例:

public void SelectedObjectsGridSelectionChangedCommand(object parameter)
{
object data = null;
IList selectedRows = parameter as IList;
if (selectedRows.Count == 1)
data = (SelectedNetObjectBindingSource)selectedRows[0]).Data;

Task.Factory.StartNew(() =>
{
ObjectProperties.Instance.SetAttributeObjectNoRefresh(null);

Parallel.Invoke(
() => SetAttributeObjectExtraHightlight<SelectedNetObjectBindingSource>(selectedRows),
() => DoSomeOtherStuff(selectedRows));

}).ContinueWith(task =>
{
((ObjectViewModel)MyApp.ViewModels["Shared.Panels.Object"]).SelectedObjectsChanged();
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}

关于c# - 如何在后台获取数据并在准备好时用数据异步更新 UI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46421435/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com