locked
Storyboard Completed event is fired with delay RRS feed

  • Question

  • Hi,

    I'm running a Storyboard from code and I noticed that the Completed event is not fired just after the animation is finished. Testing with longer animations I've noticed that the delay is almost 2x.

    Xaml:

    <Grid x:Name="AnimationTarget"
          Width="200"
          Height="200"
          Background="OrangeRed">
        <Grid.Projection>
            <PlaneProjection x:Name="AnimationTargetProjection" />
        </Grid.Projection>
    </Grid>
    <TextBlock x:Name="DebugTextBlock"
               Text="..."
               Margin="100"
               VerticalAlignment="Top" />
    <Button x:Name="AnimateButton"
            Content="Animate"
            Margin="100"
            Click="OnAnimateButtonClicked"
            VerticalAlignment="Bottom" />

    C#:

    private readonly Stopwatch _stopwatch = new Stopwatch();
    private Storyboard _storyboard;
    private readonly TimeSpan _halfTime;
    
    public MainPage()
    {
        this.InitializeComponent();
        this._halfTime = new TimeSpan(0, 0, 0, 0, 500);
        //~ this._halfTime = new TimeSpan(0, 0, 0, 3);
    }
    
    private void OnAnimateButtonClicked(object sender, RoutedEventArgs e)
    {
        this.AnimateButton.IsEnabled = false;
    
        this._storyboard = new Storyboard();
        //~ this._storyboard.Duration = new Duration(new TimeSpan(0,0,0,1));
    
        DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();
        //~ animation.Duration = new Duration(new TimeSpan(0,0,0,1));
        animation.EnableDependentAnimation = true;
        Storyboard.SetTarget(animation, this.AnimationTargetProjection);
        Storyboard.SetTargetProperty(animation, "RotationY");
        this._storyboard.Children.Add(animation);
    
        // Frame 1: Rotate to 90
        {
            EasingDoubleKeyFrame frame = new EasingDoubleKeyFrame
            {
                KeyTime = this._halfTime,
                Value = 90,
                EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseIn }
            };
    
            animation.KeyFrames.Add(frame);
        }
    
        // Frame 2: Rotate to 180
        {
            EasingDoubleKeyFrame frame = new EasingDoubleKeyFrame
            {
                KeyTime = this._halfTime + this._halfTime,
                Value = 180,
                EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut }
            };
    
            animation.KeyFrames.Add(frame);
        }
    
        this._storyboard.Completed += this.OnStoryboardCompleted;
    
        this.DebugTextBlock.Text = "...";
        this._stopwatch.Restart();
        this._storyboard.Begin();
    }
    
    private void OnStoryboardCompleted(object sender, object o)
    {
        this._stopwatch.Stop();
    
        var elapsedMilliseconds = this._stopwatch.ElapsedMilliseconds;
        var expected = 2 * this._halfTime.TotalMilliseconds;
    
        this.DebugTextBlock.Text =
            string.Format("Completed in: {0:0.00}ms\r\nExpected: {1:0.00}ms\r\nDelay: {2:0.00}ms",
                elapsedMilliseconds, expected, elapsedMilliseconds - expected);
    
        this._storyboard.Completed -= this.OnStoryboardCompleted;
        this.AnimateButton.IsEnabled = true;
        this._storyboard = null;
    }

    Clicking the animate button few times gives different results. Sometimes the Completed event is fired on time (~1000ms after the animation is started), sometimes it's delayed (~2000 ms).

    Can you reproduce this behavior and is there something I can do to fix the code above so that Completed is fired when the animations is visually finished?

    Full sample: http://sdrv.ms/1gGZSNu - AnimationCompletedSample.zip

    P.S. Later while debugging the storyboard I was running a DispatcherTimer with a small interval (50ms). While running the timer the storyboard completes almost on time. It seems like the messages pushed on the UIThread for the timer affect the storyboard completion.

    Thanks,
    Nik


    • Edited by Nik.Z Thursday, January 9, 2014 4:09 PM
    Thursday, January 9, 2014 4:08 PM

Answers

  • I've just tried on few other devices (Surface Pro, Surface RT, Acer Iconia W7 and another Toshiba LX830) and I was not able to reproduce it. It seems like it only happens on my machine (Toshiba LX830 - All-in-One PC). I'll install the latest windows updates and try again.

    Update:
    I cannot reproduce the issue after installing these updates:

    Security Update for Windows 8.1 for x64-based Systems (KB2893984)
    Update for Windows 8.1 for x64-based Systems (KB2883200)
    Security Update for Windows 8.1 for x64-based Systems (KB2868626)
    Update for Windows 8.1 for x64-based Systems (KB2904266)
    Update for Windows 8.1 for x64-based Systems (KB2903939)
    Security Update for Windows 8.1 for x64-based Systems (KB2892074)
    Update for Windows 8.1 for x64-based Systems (KB2887595)
    Update for Windows 8.1 for x64-based Systems (KB2902892)
    Security Update for Windows 8.1 for x64-based Systems (KB2876331)
    Security Update for Windows 8.1 for x64-based Systems (KB2862152)
    Security Update for Windows 8.1 for x64-based Systems (KB2893294)
    Update for Windows 8.1 for x64-based Systems (KB2884846)

    I'm not sure which one fixes the problem, but I guess it is KB2883200

    Thanks,
    Nik


    • Edited by Nik.Z Friday, January 10, 2014 10:37 AM
    • Marked as answer by Nik.Z Monday, January 13, 2014 7:53 AM
    Friday, January 10, 2014 10:12 AM

All replies

  • Hi Nik.Z,

    Thank you for the code, but I cannot reproduce your issue, the time spent always near 1000ms, the largest delay I've seen is 23ms which is acceptable.

    I would suggest you to test the same code on a different machine to see if the same delay happens. And you could use "Performance and Diagnostics" tool to help with analyzing the app animation. I capture the result of your app while running in my environment as below:

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Friday, January 10, 2014 7:31 AM
    Moderator
  • I've just tried on few other devices (Surface Pro, Surface RT, Acer Iconia W7 and another Toshiba LX830) and I was not able to reproduce it. It seems like it only happens on my machine (Toshiba LX830 - All-in-One PC). I'll install the latest windows updates and try again.

    Update:
    I cannot reproduce the issue after installing these updates:

    Security Update for Windows 8.1 for x64-based Systems (KB2893984)
    Update for Windows 8.1 for x64-based Systems (KB2883200)
    Security Update for Windows 8.1 for x64-based Systems (KB2868626)
    Update for Windows 8.1 for x64-based Systems (KB2904266)
    Update for Windows 8.1 for x64-based Systems (KB2903939)
    Security Update for Windows 8.1 for x64-based Systems (KB2892074)
    Update for Windows 8.1 for x64-based Systems (KB2887595)
    Update for Windows 8.1 for x64-based Systems (KB2902892)
    Security Update for Windows 8.1 for x64-based Systems (KB2876331)
    Security Update for Windows 8.1 for x64-based Systems (KB2862152)
    Security Update for Windows 8.1 for x64-based Systems (KB2893294)
    Update for Windows 8.1 for x64-based Systems (KB2884846)

    I'm not sure which one fixes the problem, but I guess it is KB2883200

    Thanks,
    Nik


    • Edited by Nik.Z Friday, January 10, 2014 10:37 AM
    • Marked as answer by Nik.Z Monday, January 13, 2014 7:53 AM
    Friday, January 10, 2014 10:12 AM