2

より正確な見出しを付けることができず申し訳ありませんが、これが私がやりたいことです。fooいくつかのUIアニメーションを開始するメソッドがあります。これらのアニメーションが終了したら、メソッドの完了を通知したいと思います。ただし、イベントを介して完了を通知する代わりに、メソッドを作成したいと思いawaitableます。これはどのように行うことができますか?

void foo()
{  
  // start some animations 
   storyboard.Begin();
   storyboard.Completed += (s, e) => { // signal that foo has completed }
}

呼び出しコードは次のように記述できる必要があります。

await foo();

私の実際fooのアニメーションは、次々に発生する一連のアニメーションがあり、fooすべてのアニメーションが完了すると完了するはずであるという点で、上の図よりも複雑です。

4

2 に答える 2

5

通常、イベントに基づいて完了するものは、TaskCompletionSource を使用して「ラップ」されます。残念ながら、MSDN の例は (IMHO) 単一のインスタンス + イベントではなく、非常に複雑です。次のようなものがあります。

public Task Foo()
{
    var tcs = new TaskCompletionSource<bool>();
    storyboard.Begin();
    storyboard.Completed += (s, e) => tcs.SetResult(true);
    return tcs.Task;
}

このシナリオでは、TResult は実際には必要ありませんが、TaskCompletionSource には非ジェネリック バージョンがないようであり、同等のパターンが何であるかはわかりません。

于 2012-06-12T04:19:43.697 に答える
0

私は最近、Begin() を呼び出す前にイベント ハンドラーを設定しても、Completed イベントが時間どおりに発生しないか、まったく発生しない状況に遭遇しました (これは、私が見つけた他のほとんどの関連投稿の原因でした)。 . そのため、アニメーションが終了するのを待ってから、同じ方法で続行する方法を探していました。最終的に、待ちたいストーリーボードをパラメーターとして受け取る以下の静的メソッドを作成しました。

public async static Task RunStoryboard(Storyboard Story)
{
    Story.Begin();
    while (Story.GetCurrentState() == ClockState.Active && Story.GetCurrentTime() < Story.Duration)
    {
        await Task.Delay(100);
    }
}

2 番目の条件を追加したのは、Completed イベントが発生しない状況では、アニメーションが終了した後でも、ClockState が常にアクティブとして表示されるためです。そのため、ストーリーボードの期間を明示的に設定する必要がありますが、これまでのところうまく機能しています。

于 2015-12-22T00:03:44.907 に答える