0

私のローカルボックスでは、次のコードが機能します:

 public async Task<GameStatistic> LoadReport()
    {
        var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(FolderName, CreationCollisionOption.OpenIfExists);
        var file = await folder.GetFileAsync(FileName);

        GameStatistic returnValue;
        using (var inStream = await file.OpenSequentialReadAsync())
        {
            var serializer = new DataContractJsonSerializer(typeof (GameStatistic));
            returnValue = serializer.ReadObject(inStream.AsStreamForRead()) as GameStatistic;
        }
        return returnValue;
    }

上記のメソッドを呼び出すコード:

  public GameStatistic GetReportData()
    {
        var repo = new GameRepository();
        var gameStatTask = repo.LoadReport(); //(awaitable) Task<GameStatistic>

        gameStatTask.Wait();  //this seems to make no difference
        return gameStatTask.Result;
    }

しかし、コードを Surface Pro に移動してアプリケーションを実行すると (デバッガーなし)、folder.GetFileAsync(FileName)フォルダーを取得するための非同期呼び出しがまだ返されていないため、失敗します。

Surface Pro で (リモート マシン経由で) アプリケーションをデバッグし、デバッガーをゆっくりとコードの最初の行を通過させ、数秒待ってからもう一度ステップを踏むと、すべてが機能します。

任意の長さのスレッドをスリープ状態にしようとする考えは好きではありませんが、ここで他に何ができるかわかりません。

私が間違っていること、または私がまったくしていないことはありますか? 前の行が完了したことを確認できるように、CreateFolderAsync が返されるまで実際に待機する一般的な方法はありますか?

ご協力いただきありがとうございます。

4

1 に答える 1

0

@JB が指摘しているようawaitに、 の代わりに使用する必要がありwaitます。また、asyncメソッドを呼び出す関数は、それ自体である必要がありますasync(これには少なくとも 1 つの例外があります)。そのため、UI までのコール スタックのほぼ全体を次のバリエーションに変更する必要がありますasync Task<...>...

async public Task<GameStatistic> GetReportData()
{
    var repo = new GameRepository();
    return await repo.LoadReport(); //(awaitable) Task<GameStatistic>
}

上記の呼び出し元 (任意のメソッド):

async public Task<MyResultClass> GetReportAndResult()
{
     var gameStat = await GetReportData();
     return ReportDataToMyResult(gameStat);
}

呼び出しチェーン (イベント ハンドラー) の先頭はasync void次のとおりです。

async void GetReportData_ButtonClick(...)
{
    var result = await GetReportAndResult();
    // do something with result
    // ...
}
于 2013-04-28T18:33:19.063 に答える