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 上的示例(恕我直言)过于复杂,而不仅仅是单个实例+事件。你会有类似的东西:

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

我最近遇到了 Completed 事件没有按时触发,或者有时根本没有触发的情况,即使我在调用 Begin() 之前设置了事件处理程序(这是我发现的大多数其他相关帖子的罪魁祸首) . 所以我一直在寻找一种方法来等待动画结束,然后以相同的方法继续。我最终创建了以下静态方法,该方法将您要等待的情节提要作为参数。

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

我添加了第二个条件,因为在 Completed 事件从未触发的情况下,ClockState 将始终显示为活动状态,即使在动画完成后也是如此。因此,这需要明确设置情节提要的持续时间,但到目前为止它对我来说效果很好。

于 2015-12-22T00:03:44.907 回答