uwp c#异步方法等待数据未完全加载异常

问题描述:

我会尽量以尽可能简单的语言告诉我的问题。 在我UWP的应用程序,我加载数据异步聪明我Mainpage.xaml.cs`uwp c#异步方法等待数据未完全加载异常

public MainPage() 
{ 
    this.InitializeComponent(); 
    LoadVideoLibrary(); 
} 

private async void LoadVideoLibrary() 
{ 
    FoldersData = new List<FolderData>(); 
    var folders = (await Windows.Storage.StorageLibrary.GetLibraryAsync 
        (Windows.Storage.KnownLibraryId.Videos)).Folders; 
    foreach (var folder in folders) 
    { 
     var files = (await folder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByDate)).ToList(); 
     FoldersData.Add(new FolderData { files = files, foldername = folder.DisplayName, folderid = folder.FolderRelativeId }); 

    } 
    } 

所以这是我加载了FolderData对象的List的代码。 有在我的其他页面Library.xaml.cs我正在使用该数据加载我的GridView与绑定数据。

protected override void OnNavigatedTo(NavigationEventArgs e) 
    { 
     try 
     { 
      LoadLibraryMenuGrid(); 
     } 
     catch { } 
    } 

    private async void LoadLibraryMenuGrid() 
    { 
     MenuGridItems = new ObservableCollection<MenuItemModel>(); 
     var data = MainPage.FoldersData; 
     foreach (var folder in data) 
     { 

      var image = new BitmapImage(); 
      if (folder.files.Count == 0) 
      { 
       image.UriSource = new Uri("ms-appx:///Assets/StoreLogo.png"); 
      } 
      else 
      { 
       for (int i = 0; i < folder.files.Count; i++) 
       { 
        var thumb = (await folder.files[i].GetThumbnailAsync(Windows.Storage.FileProperties.ThumbnailMode.VideosView)); 
        if (thumb != null) { await image.SetSourceAsync(thumb); break; } 

       } 
      } 

      MenuGridItems.Add(new MenuItemModel 
      { 
       numberofvideos = folder.files.Count.ToString(), 
       folder = folder.foldername, 
       folderid = folder.folderid, 
       image = image 
      }); 
     } 
     GridHeader = "Library"; 
    } 

我面临的问题是,当我启动我的应用程序,等待几秒钟,然后我浏览到我的图书馆网页,所有的数据加载正确。

但是当我尝试启动应用后立即导航到库页面,它给出了

“集合被修改,因此它不能被重复”

我用的断点异常我知道,如果我给它几秒钟的列表文件夹数据已被正确加载asyncornously,但是当我dnt给它几秒钟,异步方法加载数据的一半,所以它会导致异常,如何我可以处理这种异步情况吗?谢谢

+1

http://stackoverflow.com/a/604843/447156? –

+0

我的情况有点不同,我知道异常的原因,很明显,但我不知道如何解决它,bcz我没有太多的异步编程经验 –

您需要的是一种等待数据到达的方式。你如何适应其他应用程序(例如MVVM)是一个不同的故事,现在并不重要。不要过分复杂的事情。例如,如果您希望在查看数据的同时更改数据,则只需要一个ObservableCollection。

无论如何,你需要等待。那么你如何等待这些数据到达?

使用一个可以从任何地方到达的静态类。在那里提供一个方法来获取你的数据。确保它返回一个您为将来的呼叫缓存的任务。例如:

internal class Data { /* whatever */ } 

internal static class DataLoader 
{ 
    private static Task<Data> loaderTask; 

    public static Task<Data> LoadDataAsync(bool refresh = false) 
    { 
     if (refresh || loaderTask == null) 
     { 
      loaderTask = LoadDataCoreAsync(); 
     } 

     return loaderTask; 
    } 

    private static async Task<Data> LoadDataCoreAsync() 
    { 
     // your actual logic goes here 
    } 
} 

使用此功能,您可以在启动应用程序后立即开始下载。

await DataLoader.LoadDataAsync(); 

当您需要其他屏幕中的数据时,再次调用该方法。它不会再次下载数据(除非您设置刷新为真),但只是等待您之前开始完成的工作(如果尚未完成)。

+0

谢谢你这么多@kris很好解释答案和它完全解决了我的问题,谢谢:) –

我知道你没有足够的经验。存在多个问题,没有解决方案,你正在加载数据。

你需要的是一个服务,可以给你的FolderData的ObservableCollection。我认为MVVM在这种情况下可能会出界,除非您愿意花费几个小时的时间。尽管在这种情况下MVVM会让事情变得更容易。

主要问题在于此 您正在使用foreach迭代文件夹和FolderData列表。如果底层收藏发生变化,则Foreach无法继续。

首先,您需要开始使用for循环而不是foreach。第二,添加一个状态来表示加载是否完成。最后使用可观察的数据源。在我早期的时候,我曾经在App.xaml.cs中创建静态属性,我曾经使用它们来共享/观察其他数据。

+0

是的,它令我感到困惑bcz我dnt有很多经验异步编程。 FolderData是一个静态列表,但它是一个简单的列表和不可观察的列表,所以我应该让它可观察? –

+0

是的,我是可观察的收集现在它没有例外,但当我再次尝试立即访问该页面时,我的一半数据被加载,而一半是没有。有没有一种简单的方法,我可以等待该方法,以便我可以知道FolderData何时填满了所有数据,因此我可以继续使用它?如果是的话请你能指导我吗?谢谢 –

+0

你需要做的是绑定可观察到的集合Xaml ..现在你手动创建项目..与绑定它会自动更新视图时收集得到修改 –