2012-03-05 1 views
0

にStorageFileから適切にすべてのファイルを読み取ることができません、私が入れたコードは以下の通りです:は私がWindows 8のメトロアプリケーションで簡単なアプリケーションを開発していると私はPicturesLibraryからファイルを取得しようとしているmはWindows 8のメトロアプリケーション

public async void Initialize() 
{ 
    IReadOnlyList<StorageFile> storageFiles = await KnownFolders.PicturesLibrary.GetFilesAsync();    
    foreach (var storageFile in storageFiles) 
    { 
     BitmapImage bitmapImage = new BitmapImage(); 
     FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read); 
     bitmapImage.SetSource(stream); 
     Image image = new Image(); 
     image.Source = bitmapImage; 
     Images.Add(image); 
    } 
} 

次に、ImageSourceを使用してこれらの画像を表示します。 私が出会っている問題は、ときにはそれがすべての、時には1つの または2つ、時にはイメージを表示しないことを示していることです。これが待ち受け可能なメソッドGetFileAsync()または他のもの欠落している可能性があります事前に

感謝:)

+0

NON-asyncメソッドを試してみて、すべてのファイルが一貫して取得できるのはなぜですか? –

+0

@jberger - そのようなAPIは利用できません。MetroにはSilverlightのように多くの非同期機能しかありません。 –

+0

私はまだasync/awaitに慣れていませんが、 'StorageFolder.GetFilesAsync()'は 'IAsyncOperation 'を返し、 'Completed'イベントを返します。 –

答えて

1

私はそれだけでタイミングの問題だと思うだろうが、foreachの中にブレークポイントまたはトレースポイントを行うことは確かに言うだろう。

は、私はあなたの問題は、この行になります

+0

ありがとうございます@ジェームズ、ええと私はあなたが言ったようにタイミングの問題だと思う、私はそのforeachループ内のいくつかのブレークポイントを試して、それはよりうまくいったが、私は実際に非同期操作に精通していないので、あなたが私にそれのためのいくつかのリンクをくれれば、とても感謝しています。ありがとうございました。 –

+0

メソッド宣言のTaskをvoidに変更し、呼び出し元が非同期でもよいかどうかに応じて、呼び出し元を待ちます。 –

+0

非常に@Jamesありがとうございます。おかげありがとう感謝:) –

0

考えることができるタスクを返すために、これを変更してみて、あなたの呼び出し元にそれを待っています。

FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read); 

ループ内で待っていると、奇妙な範囲の問題が発生する可能性があります。
まず、このループの最初の2行を切り替えてみます。

FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read); 
BitmapImage bitmapImage = new BitmapImage(); 

参考になるのは、bitmapImageです。これで問題が解決しない場合は、.ContinueWithメソッドを参照する必要があります。

storageFile.OpenAsync(FileAccessMode.Read).ContinueWith(task => { 
    FileRandomAccessStream stream = (FileRandomAccessStream)task.Result; 
    BitmapImage bitmapImage = new BitmapImage(); 
    bitmapImage.SetSource(stream); 
    Image image = new Image(); 
    image.Source = bitmapImage; 
    Images.Add(image); 
}); 
+0

こんにちは@Chris、私はそれらの2つの行を切り替えようとしましたが、.ContinueWith()メソッドの定義がなくても動作しませんでした。ご協力いただきありがとうございます 。 –

0

[OK]を、私はコンストラクタができませんので、OnNavigateToイベントにすべてのことを呼び出して

public async Task Initialize() 
     { 
      IReadOnlyList<StorageFile> storageFiles = await KnownFolders.PicturesLibrary.GetFilesAsync();    
      foreach (var storageFile in storageFiles) 
      { 
       var image = new Image(); 
       image.Source = await GetBitmapImageAsync(storageFile); 
       Images.Add(image); 
      } 
     } 

     public async Task<BitmapImage> GetBitmapImageAsync(StorageFile storageFile) 
     { 
      BitmapImage bitmapImage = new BitmapImage(); 
      IAsyncOperation<IRandomAccessStream> operation = storageFile.OpenAsync(FileAccessMode.Read); 
      IRandomAccessStream stream = await operation; 
      bitmapImage.SetSource(stream); 
      return bitmapImage; 
     } 

、私はコードを少し再配置しなければならなかった、あなたたちにこの感謝のための解決策を見つけました非同期である

protected override async void OnNavigatedTo(NavigationEventArgs e) 
     { 
      _imageList = new ImagesList(); 
      await _imageList.Initialize(); 
      foreach (var image in _imageList.Images) 
      { 
       Image img = new Image() { Source = image.Source }; 
       img.Width = img.Height = 200; 
       img.Margin = new Thickness(20, 0, 20, 0); 
       img.ImageFailed += image_ImageFailed; 
       img.PointerEntered += img_PointerEntered; 
       img.PointerExited += img_PointerExited; 
       sp_MainStackPanel.Children.Add(img); 
      } 
     } 

ありがとう!

+0

FWIWでは、 'await _imageList.Initialize()'を '_imageList.Initialize()。Wait()'に変更してからコードをctorに入れることができます(その時点で同期して実行され、 )。非同期APIを使用していて呼び出し元を非同期にしたくない場合は、返されたTaskと通常対話するだけです(たとえば、Wait()を呼び出すなど)。呼び出し側が非同期になるようにするには、「待つ」必要があります:) –