我正在开发一个简单的应用程序,它具有一个负责通过 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>
第一:使用 async void 而不保留任务可能会导致未处理的异常。
第二:RefreshBtnCommand 的代码 - 在非 UI 线程中创建集合:
ShowList = result.ToList();
UI 线程可能无法访问对象,因为它们不属于它。
第三:还需要避免在上一个命令仍在执行时启动该命令。
不要“重新发明轮子” - 在 GitHub 上,您可以找到 IAsyncCommand 的实现。例如来自 ComunityToolkit 的 AsyncRelayCommand。