简体   繁体   English

如何使动画可以期待?

[英]How to make animation awaitable?

Sorry about not being able to give a more precise headline, but here is what I want to do. 很抱歉无法提供更准确的标题,但这是我想做的。 I have a method foo which will initiate some UI animations. 我有一个方法foo ,它将启动一些UI动画。 When these animations are finished, I want to signal completion of the method. 这些动画完成后,我要表示方法已完成。 But instead of signaling completion through an event, I would like to make the method awaitable . 但是,我不想让事件通过信号通知完成,而是希望该方法可以awaitable How can this be done? 如何才能做到这一点?

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

calling code should be able to write: 调用代码应该能够编写:

await foo();

My actual foo is more complex than illustration above, in that I have a series of animations, which occur one after another, and foo is supposed to complete when all animations are completed. 我的实际foo比上面的插图更复杂,因为我有一系列动画,它们接连发生,并且foo应该在所有动画完成后完成。

Generally things that complete based on an event get 'wrapped' by using a TaskCompletionSource. 通常,通过使用TaskCompletionSource来“包装”基于事件完成的事情。 Unfortunately, the example on MSDN is (IMHO) overly complicated instead of just being a single instance+event. 不幸的是, MSDN上的示例 (IMHO)过于复杂,而不仅仅是一个实例+事件。 You'd have something like: 您会有类似的内容:

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

In this scenario, there's no real need for the TResult, but TaskCompletionSource doesn't appear to have a non-generic version and I'm not sure what the equivalent pattern would be 在这种情况下,没有真正的TResult需求,但是TaskCompletionSource似乎没有非通用版本,并且我不确定等效的模式是什么

I recently ran into a situation where the Completed event wasn't firing on time, or sometimes not firing at all, even if I set the event handler prior to calling Begin() (that was the culprit on most other related posts I found). 我最近遇到了这样一种情况,即使我在调用Begin()之前设置了事件处理程序,也没有按时触发Completed事件,有时甚至根本不触发(这是我发现的大多数其他相关帖子的罪魁祸首) 。 So I was looking for a way to wait for the animation to end, then continue on in the same method. 因此,我一直在寻找一种方法来等待动画结束,然后继续使用相同的方法。 I ended up creating the below static method that takes the storyboard you want to await as the parameter. 我最终创建了以下静态方法,该方法将要等待的情节提要作为参数。

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

I added the second condition because, during those situations where the Completed event never fired, the ClockState would always appear as active, even after the animation finished. 我添加第二个条件是因为,在从未触发Completed事件的那些情况下,即使动画结束后,ClockState也会始终显示为活动状态。 As such, this requires setting the Storyboard's duration explicitly, but it's been working well for me so far. 因此,这需要明确设置情节提要的持续时间,但到目前为止,它对我来说一直很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM