C# PCL中的MVVMCross异步和等待方法

C# PCL中的MVVMCross异步和等待方法,c#,xamarin,C#,Xamarin,我的MvxSpinner和ViewModel绑定有点问题。它似乎没有在我的微调器中显示任何数据 我的ViewModel调用一个实际返回数据的服务,以便我可以填充我的ViewModel,然后我的ViewModel填充我的视图 问题是,我的服务调用是异步的,在我看来,视图是在我的服务仍在尝试获取数据时首先加载的 这一切都发生在加载视图时,因此微调器绑定到我的ViewModel。在我决定使服务异步之前,这确实有效。如何确保视图获取最新的ViewModel数据 这是我的视图模型 public class

我的MvxSpinner和ViewModel绑定有点问题。它似乎没有在我的微调器中显示任何数据

我的ViewModel调用一个实际返回数据的服务,以便我可以填充我的ViewModel,然后我的ViewModel填充我的视图

问题是,我的服务调用是异步的,在我看来,视图是在我的服务仍在尝试获取数据时首先加载的

这一切都发生在加载视图时,因此微调器绑定到我的ViewModel。在我决定使服务异步之前,这确实有效。如何确保视图获取最新的ViewModel数据

这是我的视图模型

public class HomeViewModel
    : MvxViewModel
{

    string PracticeName = string.Empty;

    private readonly IMvxMessenger _messenger;
    private readonly IHomeService _homeService;
    public HomeViewModel(IHomeService homeService, IMvxMessenger messenger)
    {
        _homeService = homeService;
        _messenger = messenger;
        GetPractice ();
        _homeService.GetReportList(this);
    }

    public HomeViewModel()
    {

    }


    private async void GetPractice()
    {
        try 
        {
            _practiceItems = await _homeService.GetPracticeList(this);
        } 
        catch (Exception ex) 
        {
            //return null;
        }
    }

    public class Practices
    {
        public string ErrorMessage { get; set; }

        public List<string> Practice { get; set; }
    }

    private List<string> _practiceItems;
    public List<string> PracticeItems
    {
        get { return _practiceItems; }
        set { _practiceItems = value; RaisePropertyChanged(() => PracticeItems); }
    }
}
公共类HomeViewModel
:MvxViewModel
{
string PracticeName=string.Empty;
专用只读IMvxMessenger\u messenger;
私人只读IHomeService\u homeService;
公共HomeViewModel(IHomeService homeService、IMVX messenger messenger)
{
_家庭服务=家庭服务;
_信使=信使;
GetPractice();
_homeService.GetReportList(此);
}
公共HomeViewModel()
{
}
私有异步void GetPractice()
{
尝试
{
_practiceItems=Wait _homeService.GetPracticeList(本);
} 
捕获(例外情况除外)
{
//返回null;
}
}
公共课堂实践
{
公共字符串错误消息{get;set;}
公共列表实践{get;set;}
}
私人执业项目清单;
公开名单实习项目
{
获取{return\u practiceItems;}
设置{u practiceItems=value;RaisePropertyChanged(()=>practiceItems);}
}
}
这是我的服务

public class HomeService : IHomeService
{
    public HomeService()
    {

    }

    public async Task<List<string>> GetPracticeList(HomeViewModel viewModel)
    {
        HomeViewModel.Practices rootobject = null;
        var client = ClientHandler.Client;

        client.BaseAddress = new Uri("http://10.1.20.106/sdf");

        HttpResponseMessage msg = await client.GetAsync (string.Format ("api/practice?username={0}", ClientHandler.Username));
        if(msg.IsSuccessStatusCode)
        {
            var res = await msg.Content.ReadAsStringAsync();
            rootobject = JsonConvert.DeserializeObject<HomeViewModel.Practices>(res);
            if (!string.IsNullOrEmpty (rootobject.ErrorMessage)) 
            {
                return null;
            }
            //return rootobject.Practice;
        }

        return rootobject.Practice;
    }   
}
公共类家庭服务:IHomeService
{
公共家居服务()
{
}
公共异步任务GetPracticeList(HomeViewModel viewModel)
{
HomeViewModel.Practices rootobject=null;
var client=ClientHandler.client;
client.BaseAddress=新Uri(“http://10.1.20.106/sdf");
HttpResponseMessage msg=await client.GetAsync(string.Format(“api/practice?username={0}”,ClientHandler.username));
if(消息IsSuccessStatusCode)
{
var res=await msg.Content.ReadAsStringAsync();
rootobject=JsonConvert.DeserializeObject(res);
如果(!string.IsNullOrEmpty(rootobject.ErrorMessage))
{
返回null;
}
//返回根对象。实践;
}
返回根对象。实践;
}   
}

还要注意的是,此视图仅在上一个视图单击按钮导航到此视图之后出现。

请在下面的
wait
关键字之后,强制调用
RaisePropertyChanged

private async void GetPractice()
{
    try 
    {
        _practiceItems = await _homeService.GetPracticeList(this);
        RaisePropertyChanged(() => PracticeItems); 
    } 
    catch (Exception ex) 
    {
        //return null;
    }
}
我相信现代(至少从第五个主要版本开始)实现这一点的方法是(1)在property setter中使用SetProperty()基类“方法来设置属性支持字段值,以及(2)通过设置属性值用代码重写async Initialize():

private List<string> _practiceItems;
public List<string> PracticeItems
{
    get => _practiceItems;
    set => SetProperty(ref _practiceItems, value);
}

public override async Task Initialize()
{
    await base.Initialize();        
    PracticeItems = await _homeService.GetPracticeList(this);
}
private List\u practiceItems;
公开名单实习项目
{
获取=>\u实践项目;
set=>SetProperty(参考实践项目,值);
}
公共重写异步任务初始化()
{
等待base.Initialize();
PracticeItems=Wait _homeService.GetPracticeList(本);
}
这种方法的好处是,如果新值与当前值不同,SetProperty()会处理NotifyPropertyChanged,并且您可以使用适当的位置从中调用异步方法(因为从构造函数调用异步方法肯定不是一种好的做法)