WPF ViewModel AsyncCommand 冻结整个 UI

问题描述 投票:0回答:1

我正在开发一个简单的应用程序,它具有一个负责通过 MediatR 加载数据的数据网格。为了促进单击按钮时的数据刷新功能,我实现了一个 AsyncCommand,从特定的文章中汲取灵感。然而,在触发refreshBtnCommand时,我遇到了一个问题:每次重新加载数据或在不同页面之间交换时,整个UI都会冻结几秒钟。我不确定这个问题的根源,并且非常感谢任何解决方案或纠正它的指导。

public abstract class AsyncCommandBase : IAsyncCommand
{
    public abstract bool CanExecute(object parameter);
    public abstract Task ExecuteAsync(object parameter);
    public async void Execute(object parameter)
    {
        await ExecuteAsync(parameter).ConfigureAwait(false);
    }
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    protected void RaiseCanExecuteChanged()
    {
        CommandManager.InvalidateRequerySuggested();
    }
}

public class MainPageViewModel : BindableBase
{
    private readonly IMediator _mediator;
    public IAsyncCommand RefreshBtnCommand { get; private set; }
    
    public MainPageViewModel(IMediator mediator)
    {
        _mediator = mediator;

        RefreshBtnCommand = new AsyncCommand<int>(async () => {
            var result = await _mediator.Send(new GetDataRequest()
            {
                PageNumber = 1,
                PageSize = 20,
            });
            ShowList = result.ToList();
            return result.Count;
        }
        );
    } private IList<DataDto> _showList;

    public IList<DataDto> ShowList {
        get { return _showList; }
        set {
            if (_showList!= value) {
                _showList= value;
                OnPropertyChanged(nameof(ShowList));
            }
        }
    }

Xaml

<Grid>
        <DataGrid Name="ShowDg" ItemsSource ="{Binding ShowList}">
            <DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <StackPanel>
                        <DataGrid Name="childList" ItemsSource="{Binding ChildList1}">
                        </DataGrid>
                    </StackPanel>
                </DataTemplate>
            </DataGrid.RowDetailsTemplate>
        </DataGrid>
    </Grid>
c# .net wpf asynchronous async-await
1个回答
0
投票

第一:使用 async void 而不保留任务可能会导致未处理的异常。

第二:RefreshBtnCommand 的代码 - 在非 UI 线程中创建集合:
ShowList = result.ToList();
UI 线程可能无法访问对象,因为它们不属于它。

第三:还需要避免在上一个命令仍在执行时启动该命令。

不要“重新发明轮子” - 在 GitHub 上,您可以找到 IAsyncCommand 的实现。例如来自 ComunityToolkit 的 AsyncRelayCommand

© www.soinside.com 2019 - 2024. All rights reserved.