2016-03-01 92 views
0

我會盡量以儘可能簡單的語言告訴我的問題。 在我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我沒有太多的異步編程經驗 –

回答

2

您需要的是一種等待數據到達的方式。你如何適應其他應用程序(例如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很好解釋答案和它完全解決了我的問題,謝謝:) –

1

我知道你沒有足夠的經驗。存在多個問題,沒有解決方案,你正在加載數據。

你需要的是一個服務,可以給你的FolderData的ObservableCollection。我認爲MVVM在這種情況下可能會出界,除非您願意花費幾個小時的時間。儘管在這種情況下MVVM會讓事情變得更容易。

主要問題在於此 您正在使用foreach迭代文件夾和FolderData列表。如果底層收藏發生變化,則Foreach無法繼續。

首先,您需要開始使用for循環而不是foreach。第二,添加一個狀態來表示加載是否完成。最後使用可觀察的數據源。在我早期的時候,我曾經在App.xaml.cs中創建靜態屬性,我曾經使用它們來共享/觀察其他數據。

+0

是的,它令我感到困惑bcz我dnt有很多經驗異步編程。 FolderData是一個靜態列表,但它是一個簡單的列表和不可觀察的列表,所以我應該讓它可觀察? –

+0

是的,我是可觀察的收集現在它沒有例外,但當我再次嘗試立即訪問該頁面時,我的一半數據被加載,而一半是沒有。有沒有一種簡單的方法,我可以等待該方法,以便我可以知道FolderData何時填滿了所有數據,因此我可以繼續使用它?如果是的話請你能指導我嗎?謝謝 –

+0

你需要做的是綁定可觀察到的集合Xaml ..現在你手動創建項目..與綁定它會自動更新視圖時收集得到修改 –