我从一个XML文件反序列化对象的列表,并希望结合在我看来,这些对象的实际内容,在经过一个视图模型。 问题是,文件操作是async
和这个气泡一路攀升到视图模型,其中地产干将不能被标记为这样的...
问题
我反序列化所有的XML文件的文件夹中,以
Profile
的对象并将其存储在一个List<Profile>
。 该方法(必须是)标记的async
。public static async Task<List<Profile>> GetAllProfiles() { DataContractSerializer ser = new DataContractSerializer(typeof(Profile)); StorageFolder folder = await ApplicationData.Current.RoamingFolder.CreateFolderAsync("Profiles", CreationCollisionOption.OpenIfExists); List<Profile> profiles = new List<Profile>(); foreach (var f in await folder.GetFilesAsync()) { var fs = await f.OpenStreamForReadAsync(); profiles.Add((Profile)ser.ReadObject(fs)); fs.Dispose(); } return profiles; }
理想的解决方案1
然后在我的ViewModel的绑定属性将理想这样调用静态方法
public async Task<ObservableCollection<string>> Lists { get { return new ObservableCollection<string>(GetAllProfiles().Select(p => p.Name)); } }
但属性不能标记
async
理想的解决方案2
public ObservableCollection<string> Lists
{
get
{
return new ObservableCollection<string>((GetAllProfiles().Result).Select(p => p.Name));
}
}
- 但是,这永远不会执行(这在块
await folder.GetFilesAsync()
调用由于某种原因)
目前的解决方案
调用一个async
该加载的结果Initialize()方法GetProfiles()
函数中的变量,然后使一个NotifyPropertyChanged("Lists")
调用:
public ViewModel()
{
Initialize();
}
public async void Initialize()
{
_profiles = await Profile.GetAllProfiles();
NotifyPropertyChanged("Lists");
}
private List<Profile> _profiles;
public ObservableCollection<string> Lists
{
get
{
if (_profiles != null)
return new ObservableCollection<string>(_profiles.Select(p => p.Name));
else
return null;
}
}
题
有没有更好的办法? 有没有办法,我还没有发现一个模式/方法?
编辑
做非UI代码时,问题的根源出现了,你不能依靠NotifyPropertyChanged做一些线程同步的东西。 - 该方法Initialize必须等待并构建函数不能异步,所以essentialy这是图案是无用的。
public MyClass()
{
Initialize();
}
public async void Initialize()
{
_profiles = await Profile.GetAllProfiles();
}
private ObservableCollection<Profile> _profiles;
public ObservableCollection<string> Lists
{
get
{
return _profiles; // this will always be null
}
}