首页 > 解决方案 > 从异步方法填充数据绑定属性的最佳方法是什么?

问题描述

我有一个简单的要求,我正在努力实现。基本上,我有一个填充了企业列表的视图。企业列表的属性体现在我的视图模型类中,该类又绑定到视图。这是一个带有业务列表的简单 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)
        };
    }

请您建议最好的模式和正确的方法,我已经知道这是错误的>谢谢

标签: c#asp.net-mvcentity-frameworkasynchronousasync-await

解决方案


我写了一篇关于这个主题的文章。

当 UI 框架要求您的代码显示某些内容时,它必须立即(同步)显示。ViewModel 构造函数和数据绑定属性应该是同步的和即时的。做网络 I/O 根本不是一种选择。即使你让它工作(这是可能的),所有这一切都会阻止你的 UI 线程,从而降低你的用户体验。

更合适的解决方案是同步初始化到加载状态(“正在加载...”消息,微调器等)并启动异步操作。然后,当操作完成时,使用实际数据更新UI。


推荐阅读