0

非同期メソッドでawaitを呼び出すメソッドがあります。

private async void LoadPic(string imageFileName)
{
    StorageFolder sf = Windows.ApplicationModel.Package.Current.InstalledLocation;
    StorageFolder subFolder = await sf.GetFolderAsync("Assets");
    StorageFile sfile = await subFolder.GetFileAsync(imageFileName);

次の行にブレークポイントを設定すると、ブレークポイントに到達することはありません。メソッドからドロップアウトして戻ります。

public PixelData GrabPixelData(string imageFileName)
{
    if (!ImageDictionary.ContainsKey(imageFileName))
    {
        // doesn't exist yet, so load it
        LoadPic(imageFileName);
    }

    PixelData pd = new PixelData();
    bool found = false;
    while( found == false ) {
        found = ImageDictionary.TryGetValue(imageFileName, out pd);
    }
    return pd;
   // throw new NullReferenceException();
}

LoadPic()を呼び出した後、このファイルの画像が辞書に追加されたかどうかを確認し続けるループを追加しました。追加されることはなく、ハングするだけです。

このメソッドは、私が抽象化した子クラスで正常に機能しました。


編集:

いくつか変更しました。これですべてが機能しているように見えますが、結果を子クラスに割り当てると、null例外エラーが発生します(デバッガーがnullを示していない場合でも!)。

それはタスクに包まれているという事実と関係があるのだろうか。

子クラス:

private async void LoadPic()
{
     // I realize the async void is to be avoided, but ... I'm not sure because there isn't anything I want it to return. Should it just return a dummy task?
     sat1.pixelData = await rootPage.GrabPixelData("sat1.png");

LoadPic:

        private async Task<PixelData> LoadPic(string imageFileName)
        {
            StorageFolder sf = Windows.ApplicationModel.Package.Current.InstalledLocation;
            StorageFolder subFolder = await sf.GetFolderAsync("Assets");
            StorageFile sfile = await subFolder.GetFileAsync(imageFileName);
...
            return pd;

GrabPixelData:

public async Task<PixelData> GrabPixelData(string imageFileName)
{
    if (!ImageDictionary.ContainsKey(imageFileName))
    {
        // doesn't exist yet, so load it
        PixelData pd = await LoadPic(imageFileName);
        ImageDictionary.Add(imageFileName, pd);
    }

    var test = ImageDictionary[imageFileName];

    return ImageDictionary[imageFileName];
}
4

1 に答える 1

4

避けるべきasync voidです。また、非同期操作の完了を検出するために共有状態をポーリングすることはできません。この種のCPU使用率により、アプリがWindowsストアから拒否される可能性があります。

LoadPicに変更することをお勧めしますTask<PixelData>。次に、ImageDictionaryをからDictionary<string, PixelData>に変更しますDictionary<string, Task<PixelData>>。この場合、メソッドGrabPixelDataは次のようになります。

public Task<PixelData> GrabPixelData(string imageFileName)
{
  if (!ImageDictionary.ContainsKey(imageFileName))
  {
    // doesn't exist yet, so load it
    ImageDictionary.Add(imageFileName, LoadPic(imageFileName));
  }

  return ImageDictionary[imageFileName];
}
于 2013-02-28T03:07:11.513 に答える