2

ストレージからファイルを開き、ファイルが正常に開かれたことを指定したブール値を返す関数があります。

private async Task<bool> SaveImage()
{
    try
    {
        await filesave.openAsync(FileAccessMode.ReadWrite)
    }
    catch()
    {
        return false;
    }

    return true;
}

await SaveImage() 関数を呼び出したいのですが、どういうわけか、これがいつ完了したかを知らせるリスナー/イベント ハンドラーが必要です。完了したら、レイアウトを新しいデータで更新したいと考えています。Windows 8 の新しい WINRT async/await async 方法論を使用して、これはどのように可能ですか? 回避策/代替手段はありますか。

イベント ハンドラー タイプのシナリオをセットアップするにはどうすればよいですか? (完了時)

4

3 に答える 3

4

awaitメソッドを呼び出すだけで、完了時に実行するコードを続けます。イベント ハンドラーを手動で登録する必要はありません。

var succeeded = await SaveImage();
// Because of the "await" keyword in the above line, the current method
// will not continue until "SaveImage" has completed its async work and
// signaled its Task
if (succeeded) { ... }

もちろん、上記のコードはawaitキーワードを使用しているため、同様にマークされたメソッド内に配置する必要がありますasyncそのメソッドがその完了を呼び出し元に通知する必要がある場合は、Taskまたはも返す必要がありTask<T>ます。例えば:

private async Task<string> MyHelperMethod() {
    var succeeded = await SaveImage();
    if (succeeded)
        return "Success";
    else
        return "Failure";
}
// then, in some other method:
    var message = await MyHelperMethod();

または、メソッド呼び出しSaveImageが行末である場合 (たとえば、ButtonClickイベントのハンドラーである場合)、次のようになりますasync void

private async void ButtonClick(object sender, EventArgs args) {
    var succeeded = await SaveImage();
    if (succeeded) { ... }
}
于 2012-08-06T03:52:14.610 に答える
0

これにはもう少しコードが必要ですが、非同期操作、進行状況、キャンセル、および一般的な完全なステータスを処理するための非常にクールで便利な方法です。これはVS2012WinrtStoreアプリでコンパイルされ、ここに表示されているようにボタンクリックで実行しました。

    private void Save_File_Click(object sender, RoutedEventArgs e)
    {
        // create your op, bool = return type, string = progress report
        IAsyncOperationWithProgress<bool, string> op;

        // Call our async operation with progress sending the file name
        op = OpenFileWithProgress("test.txt");

        //  not implemented here
        //op.Cancel(); 

        // when we get a progress update...
        op.Progress = (info, progress) =>
        {
            // I'm just giving text feed back to user here
            Debug.WriteLine(progress);
        };
        op.Completed = (info, status) =>
        {
            // check status for completion or cancellation...
            switch (status)
            {
                case AsyncStatus.Completed:
                    //  Do your completed work here
                    Debug.WriteLine("Completed");
                    break;
                case AsyncStatus.Canceled:
                    // Operation canceled - not implemented...
                    Debug.WriteLine("Canceled");
                    break;
                default:
                    // default stuff here
                    break;
            }
        };
    }

    public IAsyncOperationWithProgress<bool, string> OpenFileWithProgress(string fileName)
    {
        return System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.Run<bool, string>((token, progress) =>
            Task.Run<bool>(async () =>
            {
                progress.Report("Starting");
                try
                {
                    StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(fileName);
                }
                catch (Exception ex)
                {
                    return false;
                }

                progress.Report("Finished");

                return true;

            }, token));
    }
于 2012-12-05T15:30:09.637 に答える
0

Joeの答えは素晴らしいように見えますが、イベントの使用を主張する場合(たとえば、SaveImage()呼び出しがレイアウトの更新とは関係のないコードのさまざまな領域にある場合)、操作の完了時にイベントを発生させることができます。プレーンな古いCLRイベントを使用することも、PrismのEventAggregatorやMVVMLightのMessengerなどのpub-subパターンの実装を使用することもできます。POCEバージョンは次のようになります

public event EventHandler<Tuple<StorageFile,bool>> SaveImageCompleted;

private async Task<bool> SaveImage(StorageFile file)
{
    try
    {
        await file.OpenAsync(FileAccessMode.ReadWrite);
    }
    catch
    {
        if (SaveImageCompleted != null)
            SaveImageCompleted(this, new Tuple<StorageFile, bool>(file, false));

        return false;
    }

    if (SaveImageCompleted != null)
        SaveImageCompleted(this, new Tuple<StorageFile, bool>(file, true));

    return true;
}
于 2012-08-06T05:51:17.903 に答える