如何在事件发生时异步更新多个WPF用户控件?

如何在事件发生时异步更新多个WPF用户控件?,wpf,asynchronous,async-await,Wpf,Asynchronous,Async Await,我有一个从本机代码调用的事件处理程序。我需要在那里做一些事情,然后为4个不同的用户控件调用异步更新。其思想是事件处理程序可以继续进行,以便在本机端完成其他工作。我的第一次尝试是: interface ISelectedObjectDependent { void SelectedObjectsChanged(); } public void ObjectSelectionChanged(object sender, EventArgs e) { // this is impor

我有一个从本机代码调用的事件处理程序。我需要在那里做一些事情,然后为4个不同的用户控件调用异步更新。其思想是事件处理程序可以继续进行,以便在本机端完成其他工作。我的第一次尝试是:

interface ISelectedObjectDependent
{
    void SelectedObjectsChanged();
}

public void ObjectSelectionChanged(object sender, EventArgs e)
{
    // this is important stuff that UserControl update methods 
    // need to access
    _selectedObjectIds.Clear();
    _updateIds = true;
    Count = Interface.UI.SelectedObjects.Count;
    ObjectProperties.Instance.AttributeObject = Count == 1
            ? Interface.UI.SelectedObjects.Get().FirstOrDefault()
            : null;

    foreach (var vm in MyApp.ViewModels)
    {
        if (vm.Value is ISelectedObjectDependent)
        {
            App.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
            {
                ((ISelectedObjectDependent) vm.Value).SelectedObjectsChanged();
            }));
        }
    }
 }
实现ISelectedObjectDependent的ViewModels具有如下方法实现:

    public void SelectedObjectsChanged()
    {
        // do some stuff
        // ....
        // refresh datagrid
        ContractsItemsSource.Refresh();
    }
我的问题是:是否有更好的方法来刷新4个UserControl内容:

  • 总执行时间
  • 未响应用户界面的总时间
  • 最长的单周期无响应用户界面

  • 这是我的解决方案,它只限制最长的单个无响应时间和总无响应时间。问题是,多个非同步调用被调度并执行,而没有任何结果

    我以完全相同的方式启动异步方法,但通过跟踪调用来限制异步调用的数量。此外,如果没有必要,我根本不打电话,我有电话的顺序/优先权

    ISelectedObjectDependent.cs

    interface ISelectedObjectDependent
    {
        void SelectedObjectsChanged();
        int ExecutionOrder { get; }
        bool NeedsRefresh();
        int QueueCount { get; set; }
    }
    
    SelectedObjects.cs

        private List<ISelectedObjectDependent> _viewModels; 
    
        public void ObjectSelectionChanged(object sender, EventArgs e)
        {            
            _selectedObjectIds.Clear();
            _updateIds = true;
            Count = Interface.UI.SelectedObjects.Count;
            ObjectProperties.Instance.SetAttributeObjectNoRefresh(Count == 1
                ? Interface.UI.SelectedObjects.Get().FirstOrDefault() : null);
    
            if (_viewModels == null)
            {
                _viewModels = new List<ISelectedObjectDependent>();
    
                _viewModels = MyApp.ViewModels.Where(vm => vm.Value is ISelectedObjectDependent).Select(vm => (ISelectedObjectDependent)vm.Value)
                    .OrderBy(vm => vm.ExecutionOrder)
                    .ToList();
            }
            foreach (var vm in _viewModels)
            {
                if (vm.NeedsRefresh() && vm.QueueCount < 1)
                {
                    vm.QueueCount++;
                    App.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action) (() =>
                    {
                        vm.SelectedObjectsChanged();
                    }));
                }
            }
        }
    

    我不明白你的问题。在执行Refresh()方法期间,UI将永远不会响应。是的,你是对的。我编辑这个问题。由于测试代码为测试目的增加了慢度,我经历了更多的无响应。这正如预期的那样有效。我想问题是:“有没有更好的方法可以做到这一点?”有更好的方法可以做到什么?更新了我的问题为什么需要调用刷新?
    public class ContractsViewModel : ViewModel, ISelectedObjectDependent
    {
        // only Interface members shown here
    
        public int ExecutionOrder { get { return 4; } }
    
        public bool NeedsRefresh()
        {
            return _isVisible;
        }
        public int QueueCount { get; set; }
    
        public void SelectedObjectsChanged()
        {
            ContractsItemsSource.Refresh();
            RaisePropertyChanged("ContractCount");
            RaisePropertyChanged("InfoText");
            QueueCount--;
        }
    }