Running a Storyboard as a Task

Sometimes you have some code that needs to run after a storyboard has completed. In my case I'm working on a little board game, and after each move (which I animate using a Storyboard), I need to figure out the next move, and either start a new play-animation or pass the turn to the other player.

Therefore I run in a loop until the turn is over. You can detect when a storyboard has finished when the "Completed" event triggers, but that makes for some recursive spaghetti code. It's much easier if I could just "await" the storyboard using a task. So I created the little extension method below that makes this possible. All you have to do to start and wait for the storyboard to finish is:

    await myStoryboard.BeginAsync();

Below is the little extension method (which also serves as a general example on how you turn an event-based class into an awaitable Task using the TaskCompletionSource):

using System;
using System.Threading.Tasks;
using Windows.UI.Xaml.Media.Animation;

namespace SharpGIS
{
    public static class StoryboardExtensions
    {
        public static Task BeginAsync(this Storyboard storyboard)
        {
            System.Threading.Tasks.TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
            if (storyboard == null)
                tcs.SetException(new ArgumentNullException());
            else
            {
                EventHandler<object> onComplete = null;
                onComplete = (s, e) => {
                    storyboard.Completed -= onComplete; 
                    tcs.SetResult(true); 
                };
                storyboard.Completed += onComplete;
                storyboard.Begin();
            }
            return tcs.Task;
        }
    }
}

Note: This code is written for WinRT. If you want to use this for Silverlight or WPF, just change ‘Eventhandler<object>’ to ‘EventHandler’.

Comments (2) -

  • Hey, this looks very much like my AsyncUI library I wrote about in February. Even the method name matches! Smile

    Here's my post on the subject:
    blog.xyzzer.me/.../

    And here's the library:
    http://asyncui.codeplex.com/
    - note the library supports Windows 8 Consumer Preview, as well as WPF, Silverlight and Windows Phone with  Async CTP3. I have not been keeping it up to date there though. There is a version that I integrated into the WinRT XAML Toolkit in the WinRTXamlToolkit.AsyncUI namespace that is Windows 8 RTM only, but it has some new features that I have not had time to backport to all other platforms. Check it here:
    http://winrtxamltoolkit.codeplex.com/
  • I did not mean this is a rip off of my library. The idea is pretty simple and naming just follows the well known convention. This really is a simpler to understand description of what I did and I am merely suggesting to take a look at WinRT XAML Toolkit since it has some more similar asynchronous UI solutions that are really useful. I find the need to use something from the AsyncUI virtually every day.

Pingbacks and trackbacks (3)+

Add comment