首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在执行大量PropertyUpdates操作时避免UI锁定

在执行大量PropertyUpdates操作时避免UI锁定
EN

Stack Overflow用户
提问于 2015-03-16 23:05:13
回答 2查看 111关注 0票数 3

我正在尝试发现避免UI锁定的最好方法,当您一次对UI进行大量更新时。

基本前提是,在启动时,我的工具在后台工作进程中运行一个perforce FSTAT。这将生成一个非常大的文件及其信息列表。完成此操作后,在其RunWorkerCompleted函数中,我将此信息传播到TreeView中的UI。

然而,这涉及到大量的属性更新!这取决于它传播到的文件的数量。它可以是5000+文件。这将完全锁定UI大约3-5秒。

我想知道我是否可以异步更新UI,这样我说,一次传播10-20个文件,仍然让UI线程继续更新,以便它仍然有响应。

谢谢。

EN

回答 2

Stack Overflow用户

发布于 2015-03-16 23:21:50

如果使用属性绑定更新TreeView内部的信息,则可以将Binding.IsAsync标志设置为true。如果您不使用绑定来更新值,那么这可能是需要考虑的问题。

Binding.IsAsync Property

另一种选择是更新所有属性,但不调用属性的PropertyChanged事件(假设您正在使用INotifyPropertyChanged更新绑定),直到所有数据都已更改,然后为任务上的每个属性调用PropertyChanged事件,因此,它仍然是异步的,但即使使用5000+绑定更新,也不应花费3-5秒。

票数 2
EN

Stack Overflow用户

发布于 2015-03-17 00:18:06

你提出的许多建议最终让我得到了一个好的答案。下面是我的代码。基本上,我们可以使用ReportProgress来允许UI在运行时更新。然后根据我们希望这种情况发生的频率进行调整。下面是我的解决方案。

关键是每N个项目调用一次PropegateMetaData (我指定了25个)。然后该列表被清空。

这将调用每25个项目的报告进度,然后继续。并最终将其余部分传递给WorkerCompleted。

代码语言:javascript
复制
    public static void Refresh(List<string> refreshPaths)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;

        worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
            List<string> filesPath = null;
            if (refreshPaths == null)
            {
                filesPath = DatabaseViewModel.Instance.Records.Select(record => record.Filepath).ToList();
            }
            else
            {
                filesPath = new List<string>(refreshPaths);
            }

            if (m_Repository != null && filesPath.Count > 0)
            {
                IList<FileSpec> lfs = new List<FileSpec>();

                int index = 0;
                foreach (DataRecord rec in DatabaseViewModel.Instance.Records)
                {
                    lfs.Add(new FileSpec(new LocalPath(rec.Filepath), null));
                    index++;
                    if (index > MaxFilesIteration)
                    {
                        GetFileMetaDataCmdOptions opts = new GetFileMetaDataCmdOptions(GetFileMetadataCmdFlags.AllRevisions, null, null, 0, null, null, null);
                        worker.ReportProgress(0, m_Repository.GetFileMetaData(lfs, null));
                        lfs.Clear();
                        index = 0;
                    }
                }

                args.Result = m_Repository.GetFileMetaData(lfs, null); //pass the remaining results across
            }
        };

        worker.ProgressChanged += (sender, args) => PropegateMetaData(args.UserState as IList<FileMetaData>);
        worker.RunWorkerCompleted += (sender, args) => PropegateMetaData(args.Result as IList<FileMetaData>);
        worker.RunWorkerAsync();
    }

    private static void PropegateMetaData(IList<FileMetaData> fileList)
    {
        IList<FileMetaData> fileState = fileList as IList<FileMetaData>;
        if (fileState != null)
        {
            foreach (FileMetaData fmd in fileState)
            {
                DataRecord currentRecord = DatabaseViewModel.Instance.GetRecordByFilepath(fmd.LocalPath.Path);
                if (currentRecord != null)
                {
                    switch (fmd.Action)
                    {
                        case FileAction.Add:
                            currentRecord.P4Status = P4FileState.Added;
                            break;
                        case FileAction.Edit:
                            currentRecord.P4Status = P4FileState.Edit;
                            break;
                        case FileAction.MoveAdd:
                            currentRecord.P4Status = P4FileState.MoveAdd;
                            break;
                        default:
                            currentRecord.P4Status = P4FileState.None;
                            break;
                    }
                }
            }
        }
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29080167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档