c# - 从异步方法填充数据绑定属性的最佳方法是什么?
问题描述
我有一个简单的要求,我正在努力实现。基本上,我有一个填充了企业列表的视图。企业列表的属性体现在我的视图模型类中,该类又绑定到视图。这是一个带有业务列表的简单 MVC 应用程序。
但是,我遇到的问题是我为另一个依赖于视图模型的类派生了业务列表,它基本上类似于我称为 BusinessService 的存储库。繁忙的服务由异步方法组成,这是我的困境,当从 viewModel 的 Ctor 或属性的 getter 进行调用时,我的应用程序挂起。该调用也是对业务服务中的 EF 数据库异步调用,并且不确定对此的正确方法是什么。请看下面的代码:
视图模型:
#region Ctor
public BusinessListViewModel(IBusinessService businessService, IStringBuilder builder)
{
_businessService = businessService;
_builder = builder;
InitBusinesses().Wait(); //OPTION 1
}
#endregion
#region Properties
public IEnumerable<BusinessViewModel> _businesses;
public IEnumerable<BusinessViewModel> Businesses
{
get
{
if (_businesses == null)
{
InitBusinesses().Wait(); //OPTION 2
}
return _businesses;
}
set => _businesses = value;
}
private async Task InitBusinesses()
{
var response = await _businessService.Get();
Businesses = response.IsSuccessful
? response.Data.Select(p => new BusinessViewModel(_builder, p))
: new List<BusinessViewModel>();
}
商业服务:
#region Service Methods
public async Task<Response<IEnumerable<Models.Business>>> Get()
{
var data = await Db.Businesses.ToListAsync();
return new Response<IEnumerable<Models.Business>>
{
IsSuccessful = true,
Message = "Successful",
Data = Mapper.Map<List<Models.Business>>(data)
};
}
请您建议最好的模式和正确的方法,我已经知道这是错误的>谢谢
解决方案
我写了一篇关于这个主题的文章。
当 UI 框架要求您的代码显示某些内容时,它必须立即(同步)显示。ViewModel 构造函数和数据绑定属性应该是同步的和即时的。做网络 I/O 根本不是一种选择。即使你让它工作(这是可能的),所有这一切都会阻止你的 UI 线程,从而降低你的用户体验。
更合适的解决方案是同步初始化到加载状态(“正在加载...”消息,微调器等)并启动异步操作。然后,当操作完成时,使用实际数据更新UI。
推荐阅读
- c# - 在不使用管理证书的情况下向 Microsoft.Azure.Management.Automation.AutomationManagementClient 进行身份验证
- javascript - 在for循环的for语句之外声明“i”变量会加快循环的执行,这是什么原因呢?
- r - 更新数据框中的操作按钮
- django - 关系“”不存在
- oracle - 在交互式报告中显示来自 apex_application_temp_files 的图像
- python-3.x - 调用@classmethod 的super,它调用另一个classmethod
- compiler-errors - 为什么有些错误是无声的?
- javascript - 未捕获的 ReferenceError:未在 HTMLAnchorElement.onclick 中定义
- python - 从列表结果中选择 1 个特定值
- raku - Perl 6 阻塞等待被杀死的 Proc::Async