Can Bilgin

Just another Metro site

  • Home
  • Downloads
  • About

Async Development in WinRT – I

Posted by Can Bilgin on May 20, 2013
Posted in: Metro, Task. Tagged: asynchronous, awaitables, ContinueWith, Task.Run, Task.WhenAll, Task.WhenAny, TaskCompletionSource, Windows Store Apps, WinRT. 2 comments

When you are dealing with an application that directly interacts with a network, or works on network resources, your app is bound to make some long running calls. If we were dealing with a good old Windows Forms application, the most important point was to avoid your application from blocking the UI. We would use some background threads or a background worker, while displaying a (relatively annoying) loading sign. We could extend this pattern by using some completed or error event handlers to notify the UI about the worker thread. The basic goal here is to let the user know that the application is doing some work in the background without blocking the UI thread, hence avoiding the “MyApp is not responding” status.

In Windows Store Apps, our job is a little harder. We have to deal with the whole “Fast and Fluid” ideology of windows runtime. In other words, our application should stay responsive at all times. We can still use some subtle indicators that the application is doing something in the background but we should avoid keeping the user waiting while we are finishing up a task. In this quest of ours to make our application responsive, our biggest helper is the new asynchronous API. With this new “framework”, you can implement/use progress callbacks, task abortion, awaiter’s and so on; by means of which you can throw some of the basic plumbing on windows runtime’s back.

In this post, we will be implementing and using some of the features of this asynchronous API. For this purpose lets create a new class that works on a simple eventing pattern. We will have a long running task, a Completed handler and an error event.

Preparing Our Demo Class

So let us start by defining our class with a long running task.

NOTE: In these examples, I will be using a custom diagnostic event listener for logging. You can the ETW logging implementation for WinRT sample from the MSDN Code Gallery.

public class EventingClass
{
    private int DoTask1(int input)
    {
        int result;

        // Emulating the long running task
        Task.Delay(2000).Wait();

        if (input < 0)
        {
            throw new ArgumentOutOfRangeException("input", "Input parameter cannot be smaller than 0");
        }

        result = input + 1;

        return result;
    }
}

So our operation just waits for 2000 milliseconds and if the input value is less than 0 throws an exception. Otherwise, it will return a result value. (NOTE: Task.Delay is very similar to Thread.Sleep function from the Threading namespace).

As we described above we need two events for success and error. So we first implement the event arguments:

public class MyTaskCompletedEventArgs : EventArgs
{
    public int Result
    {
        get;
        private set;
    }
    
    public MyTaskCompletedEventArgs(int result)
    {
        Result = result;
    }
}

public class MyTaskFailedEventArgs : EventArgs
{
    public string Message
    {
        get;
        private set;
    }
 
    public MyTaskFailedEventArgs(string message)
    {
        Message = message;
    }
}

And finally we can implement the eventing pattern in our class:

public class EventingClass
{
    public event EventHandler<MyTaskFailedEventArgs> OnTaskFailed;

    public event EventHandler<MyTaskCompletedEventArgs> OnTask1Completed;

    private void RaiseOnTask1Completed(int result)
    {
        var eventHandler = OnTask1Completed;

        if (eventHandler != null)
        {
            eventHandler(this, new MyTaskCompletedEventArgs(result));
        }
    }

    private void RaiseOnTaskFailed(string message)
    {
        var eventHandler = OnTaskFailed;

        if (eventHandler != null)
        {
            eventHandler(this, new MyTaskFailedEventArgs(message));
        }
    }

    public void DoTask1AsyncWithEvent(int input)
    {
        Task.Run(() =>
        {
            try
            {
                var result = DoTask1(input);
                RaiseOnTask1Completed(result);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                RaiseOnTaskFailed(ex.Message);
            }
        });
    }
}

The reason we are using the Task.Run function is the fact that this is the easiest way to execute our function on a separate ThreadPool on windows runtime. We are just emulating the background operation with an async thread.

So now our usage for this class and its functions would be something like:

var newEventingClass = new EventingClass();
newEventingClass.OnTask1Completed += (se, args) => CustomEventSource.Log.Debug("Task1 Completed Event");
newEventingClass.OnTaskFailed += (se, args) => CustomEventSource.Log.Debug("Task1 Failed Event");

CustomEventSource.Log.Debug("Task1 Starting");
newEventingClass.DoTask1AsyncWithEvent(0);
Task.Delay(1000).Wait();
CustomEventSource.Log.Debug("Task1 Starting");
newEventingClass.DoTask1AsyncWithEvent(-1);

As a result of this execution we will have a log composed of:

2013-05-20 13:26:35:6462 Type: Verbose Id: 1 Message: ‘Here is the verbose message’
2013-05-20 13:26:35:6662 Type: Verbose Id: 1 Message: ‘Task1 Starting’
2013-05-20 13:26:36:6717 Type: Verbose Id: 1 Message: ‘Task1 Starting’
2013-05-20 13:26:37:6907 Type: Verbose Id: 1 Message: ‘Task1 Completed Event’
A first chance exception of type ‘System.ArgumentOutOfRangeException’ occurred in LocalStorage.exe
2013-05-20 13:26:39:2922 Type: Verbose Id: 1 Message: ‘Task1 Failed Event’

Great, we have an asynchronous pattern implemented using events. We can now move forward using some of the asynchronous API features.

Converting Events to Awaitables (TaskCompletionSource<T>)

One of the most useful features from the async framework is the TaskCompletionSource. Using the task awaiter developers can easily convert legacy async event implementations to awaitables. So in our example, we can actually write an additional method in our wrapper class to convert the execution for Task 1 to an awaitable.

 private Task<int> ExecuteTask1(int input)
{
    var newEventingClass = new EventingClass();

    var myTaskSource = new TaskCompletionSource<int>();

    // Subscribe to TaskCompleted: When the Task1Completed event is fired, set result.
    newEventingClass.OnTask1Completed += (sender, args) => myTaskSource.SetResult(args.Result);

    // Subscribe to TaskFailed: If there is an error in the execution, set error.
    newEventingClass.OnTaskFailed += (sender, args) => myTaskSource.SetException(new Exception(args.Message));

    // Finally execute the task and return the associated Task promise.
    newEventingClass.DoTask1AsyncWithEvent(input);

    return myTaskSource.Task;
}

As you notice from the comments, you have two main actions with the task completion source. On a successful call we set the result, on a failed call, we set the error / exception. And to actually call our method now, we can use all the features in an async awaitable call:

CustomEventSource.Log.Debug("Task1 Starting");
var taskResult = await ExecuteTask1(0);
CustomEventSource.Log.Debug("Task1 Completed");

Task.Delay(1000).Wait();

try
{
    CustomEventSource.Log.Debug("Task1 Starting");
    var errorTaskResult = await ExecuteTask1(-1);
}
catch (Exception ex)
{
    CustomEventSource.Log.Debug("Task1 Failed");
}

And as before, if we look at the log entries:

2013-05-20 13:43:47:8964 Type: Verbose Id: 1 Message: ‘Task1 Starting’
2013-05-20 13:43:49:9376 Type: Verbose Id: 1 Message: ‘Task1 Completed’
2013-05-20 13:43:50:9489 Type: Verbose Id: 1 Message: ‘Task1 Starting’
A first chance exception of type ‘System.ArgumentOutOfRangeException’ occurred in LocalStorage.exe
A first chance exception of type ‘System.Exception’ occurred in mscorlib.dll
2013-05-20 13:43:53:6639 Type: Verbose Id: 1 Message: ‘Task1 Failed’

Voilà! We converted the event based async implementation to an awaitable method.

Converting Event Pattern to Async Pattern (Task<T>>)

In the previous example, we refrained from changing the EventingClass. This class was maybe a legacy implementation, or there was quite a big amount of business logic implemented and it would be troublesome to implement awaitables.

However, what if you have access to EventingClass and the energy to rewrite the public access methods. In this case, let us get rid of all event related implementations and just deal with our async implementation.

public class EventingClass
{
    public Task<int> DoTask1AsyncWithTask(int input)
    {
        return Task.Run(() => DoTask1(input));
    }

    private int DoTask1(int input)
    {
        int result;

        // Emulating the long running task
        Task.Delay(2000).Wait();

        if (input < 0)
        {
            throw new ArgumentOutOfRangeException("input", "Input parameter cannot be smaller than 0");
        }

        result = input + 1;

        return result;
    }
}

Our long running DoTask1 method is now executed as an awaitable. And just like in the previous example, you can call it with a simple try catch block.

Chaining / Batching Tasks (ContinueWith / WhenAll / WhenAny)

Let us now assume, we have three tasks (i.e. Task1, Task2, Task3), all receiving an input parameter of integer type and returning integer. Moreover, let’s assume we have to write a function that executes all of these methods in an awaitable fashion.

For this scenario, we set the following synchronous methods to be executed.

private int DoTask1(int input)
{
    CustomEventSource.Log.Debug("Task1 Starting");

    int result;

    // Emulating the long running task
    Task.Delay(2000).Wait();

    result = input + 1;

    CustomEventSource.Log.Debug("Task1 Completed");

    return result;
}

private int DoTask2(int input)
{
    CustomEventSource.Log.Debug("Task2 Starting");

    int result;
    Task.Delay(3000).Wait();
    result = input + 2;

    CustomEventSource.Log.Debug("Task2 Completed");
    return result;
}

private int DoTask3(int input)
{
    CustomEventSource.Log.Debug("Task3 Starting");

    int result;
    Task.Delay(4000).Wait();
    result = input + 3;

    CustomEventSource.Log.Debug("Task3 Completed");

    return result;
}

If we were using the old eventing implementation we would have to chain the callbacks in the Completed events for each of these methods and handle the error. However with the ContinueWith<T> callback implementation we can easily chain these methods and have an awaitable parent function:

public Task<int> DoTasksAll(int input)
{
    var task1 = Task.Run(() => DoTask1(input));

    var task2 = task1.ContinueWith(task => DoTask2(task.Result));
            
    var task3 = task2.ContinueWith(task => DoTask3(task.Result));

    return task3;
}

And when we call this method from our UI thread with an “await”, our log would show a result similar to (i.e. let’s say the initial input was 0):

2013-05-20 14:43:06:7226 Type: Verbose Id: 1 Message: ‘Here is the verbose message’
2013-05-20 14:43:06:7246 Type: Verbose Id: 1 Message: ‘TaskAll Starting’
2013-05-20 14:43:06:7336 Type: Verbose Id: 1 Message: ‘Task1 Starting’
2013-05-20 14:43:08:7439 Type: Verbose Id: 1 Message: ‘Task1 Completed’
2013-05-20 14:43:08:7459 Type: Verbose Id: 1 Message: ‘Task2 Starting’
2013-05-20 14:43:11:7609 Type: Verbose Id: 1 Message: ‘Task2 Completed’
2013-05-20 14:43:11:7649 Type: Verbose Id: 1 Message: ‘Task3 Starting’
2013-05-20 14:43:15:7660 Type: Verbose Id: 1 Message: ‘Task3 Completed’
2013-05-20 14:43:15:7680 Type: Verbose Id: 1 Message: ‘TaskAll Completed with result: 6′

In addition to ContinueWith, you are also equipped with functions like WhenAll and WhenAny. These functions are pretty self-explanatory. And the usage pattern would look something similar to the function declaration below if these tasks we have were mutually exclusive.

public Task<int[]> DoTasksAllBatch(int input)
{
    return Task.WhenAll(
        Task.Run(() => DoTask1(input)), 
        Task.Run(() => DoTask2(input)), 
        Task.Run(() => DoTask3(input)));
}

Notice the return values is an array of results we would get from the parallel execution of these tasks. So the log we would see from calling this method would be:

2013-05-20 14:54:00:2678 Type: Verbose Id: 1 Message: ‘TaskAllBatch Starting’
2013-05-20 14:54:00:2798 Type: Verbose Id: 1 Message: ‘Task1 Starting’
2013-05-20 14:54:00:2838 Type: Verbose Id: 1 Message: ‘Task2 Starting’
2013-05-20 14:54:00:2848 Type: Verbose Id: 1 Message: ‘Task3 Starting’
2013-05-20 14:54:02:2899 Type: Verbose Id: 1 Message: ‘Task1 Completed’
2013-05-20 14:54:03:3211 Type: Verbose Id: 1 Message: ‘Task2 Completed’
2013-05-20 14:54:04:3178 Type: Verbose Id: 1 Message: ‘Task3 Completed’
2013-05-20 14:54:04:3198 Type: Verbose Id: 1 Message: ‘TaskAllBatch Completed with result: 1,2,3′

If you look at the time codes, each task started at the same time and the final completion is fired when each of them completed.

I guess this is more than enough for today. In the next post we will be talking about Progress, Cancellation and the other async features of windows runtime.

Happy coding everyone….

Image UserControl with FadeIn & FadeOut Animation for WinRT

Posted by Can Bilgin on May 14, 2013
Posted in: Metro, Transitions, WinRT. Tagged: EntranceThemeAnimation, FadeInThemeAnimation, FadeOutThemeAnimation, Image, Storyboard, UserControl, Windows Store Apps. 2 comments

One of the main design principles of Metro and Windows Store Apps is to make the UI as responsive as possible while maintaining the smooth transition effects in response to working threads.

For finished control implementation, please scroll to the bottom, unless you want to read a little more about the transitions and animations used for the control.

Following these two basic statements, we will try to solve a very common problem about using web resources in windows runtime. For this scenario, let’s assume we are working on an application that is supposed to visualize a certain dataset that is downloaded from a network source. In this dataset, let us again assume we have certain URIs that we want to use as a source to content images. The best solution for displaying a smooth layout while loading the images from this network source would be to set them to invisible until the image is loaded fully and then fade them in using a transition. (e.g. You can see a concrete example in the Bing app while it is opening the search results and loading the images)

This is not an uncommon problem and if we were dealing with WPF, we could easily deal with this using triggers.

<Style x:Key="StyleImageFadeIn" TargetType="{x:Type Image}">
    <Setter Property="Opacity" Value="0" />
    <Style.Triggers>
        <!--Sets visibility to Collapsed if Source is null - this will cause IsVisible to be false-->
        <Trigger Property="Source" Value="{x:Null}">
            <Setter Property="Visibility" Value="Collapsed" />
        </Trigger>
        <!--Fades-in the image when it becomes visible-->
        <Trigger Property="IsVisible" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard>
                    <BeginStoryboard.Storyboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:1"/>
                        </Storyboard>
                    </BeginStoryboard.Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
        </Trigger>
    </Style.Triggers>
</Style>

Beautiful, so the image is collapsed when the Source is set to null. When it becomes visible, meaning when the source is set, we nicely fade it in.

BUT… Where are the triggers in WinRT and Windows Store Apps. The answer is: “They are gone”. However, we have the new, let’s say, “packaged” version of some commonly used animations such as “EntranceThemeTransition”, “RepositionThemeTransition” etc. These “packaged” transitions can be easily included in the transitions property of the framework elements. However, these are render transitions and it would not help us in our quest to load the image from the network source and fade it in, because in most cases the render transition would actually be played before the network resource is actually loaded.

We can go ahead and use the Image controls ImageOpened property and deal with the animation on the page’s implementation but we want a more compact solution that can easily be reused in our other projects.
So let’s try to implement a user control. First thing we do is to create a grid and add an image control in it. We also need to declare the fade-in animation and possibly fade-out animations for the image.

<UserControl
    x:Class="Samples.ImagePreview"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" x:Name="ControlRoot" d:DesignHeight="300" d:DesignWidth="400">
    <Grid>
        <Image x:Name="Image" Source=" " Height="{Binding ElementName=ControlRoot, Path=ActualHeight}" Width="{Binding ElementName=ControlRoot, Path=ActualWidth}" />
        <Grid.Resources>
            <Storyboard x:Name="ImageFadeOut">
                <FadeOutThemeAnimation Storyboard.TargetName="Image" />
            </Storyboard>
            <Storyboard x:Name="ImageFadeIn">
                <FadeInThemeAnimation Storyboard.TargetName="Image" />
            </Storyboard>
        </Grid.Resources>
    </Grid>
</UserControl>

Notice that instead of using a standard DoubleAnimation on opacity we are using the FadeInThemeAnimation and the FadeOutThemeAnimation.

Next let’s declare a dependency property for the image source and another one for a placeholder (just in case).

public static readonly DependencyProperty SourceProperty =
    DependencyProperty.Register("Source", typeof(ImageSource), typeof(ImagePreview),
        new PropertyMetadata(default(ImageSource), SourceChanged));

public static readonly DependencyProperty PlaceHolderProperty =
    DependencyProperty.Register("PlaceHolder", typeof(ImageSource), typeof(ImagePreview),
    new PropertyMetadata(default(ImageSource)));

public ImageSource Source
{
    get { return (ImageSource)GetValue(SourceProperty); }
    set { SetValue(SourceProperty, value); }
}

public ImageSource PlaceHolder
{
    get { return (ImageSource)GetValue(PlaceHolderProperty); }
    set { SetValue(PlaceHolderProperty, value); }
}

So at first the PlaceHolder will be set as the source for the image control, and once the actual source is bound and loaded we can fadeout the placeholder and fade the actual image in. This process of fading out the placeholder and setting the source to the loaded image would look something like:

private void LoadImage(ImageSource source)
{
    ImageFadeOut.Completed += (s, e) =>
    {
        Image.Source = source;
        ImageFadeIn.Begin();
    };
    ImageFadeOut.Begin();
}

Once the Image control that is showing the placeholder, or another source as for that matter, is faded out, we can change the source and fade the control back in.

So only thing left to implement is a method to download the image from the network source when the bound Source is actually changed. (i.e. Notice in the dependency property declaration we already declared a callback for SourceChanged.)

private static void SourceChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
    var control = (ImagePreview)dependencyObject;
    var newSource = (ImageSource) dependencyPropertyChangedEventArgs.NewValue;

    System.Diagnostics.Debug.WriteLine("Image source changed: {0}", ((BitmapImage)newSource).UriSource.AbsolutePath);

    if(newSource != null)
    {
        var image = (BitmapImage) newSource;

        // If the image is not a local resource or it was not cached
        if (image.UriSource.Scheme != "ms-appx" && image.UriSource.Scheme != "ms-resource" && (image.PixelHeight * image.PixelWidth == 0))
        {
            // TODO:
            control.DownloadImageAsync(newSource);
        }
        else
        {
            control.LoadImage(newSource);
        }
    }
}

This implemented method is doing the usual checks, if it is a local resource it is just loading the image directly with a fade-in, if it is a remote resource, it is calling the method DownloadImageAsync (which we haven’t implemented and will not have to), which, in short, “downloads” the image as a Random Access Stream, loads it into a BitmapImage and assigns it to the image control with LoadImage method.
However, if we go down this road, you will notice that every time we open the same page with our control on it, the images will be fading in and out. Normally, when an image is opened with an image control, (unless instructed otherwise) windows runtime creates a cached version for this image data. Under normal circumstances, we would want to make use of this image caching.

The easiest option would be to create a secondary image control in the UserControl grid which will be used to load the image for the first time, and then once it is loaded assign it to the actual element. Using this “staging” element we can make use of the image caching and have a reusable control.

Below is the completed sample.

Happy coding everyone…

Finished Control

XAML:

<Grid>
    <Image x:Name="Staging" Visibility="Collapsed"/>
    <Image x:Name="Image" Source="{Binding ElementName=ControlRoot, Path=PlaceHolder}" Height="{Binding ElementName=ControlRoot, Path=ActualHeight}" Width="{Binding ElementName=ControlRoot, Path=ActualWidth}" />
    <Grid.Resources>
        <Storyboard x:Name="ImageFadeOut">
            <FadeOutThemeAnimation Storyboard.TargetName="Image" />
        </Storyboard>
        <Storyboard x:Name="ImageFadeIn">
            <FadeInThemeAnimation Storyboard.TargetName="Image" />
        </Storyboard>
    </Grid.Resources>
</Grid>

And the C# implementation:

public sealed partial class ImagePreview : UserControl
{
    public static readonly DependencyProperty SourceProperty =
        DependencyProperty.Register("Source", typeof(ImageSource), typeof(ImagePreview),
            new PropertyMetadata(default(ImageSource), SourceChanged));

    public static readonly DependencyProperty PlaceHolderProperty =
        DependencyProperty.Register("PlaceHolder", typeof(ImageSource), typeof(ImagePreview),
        new PropertyMetadata(default(ImageSource)));

    public ImageSource Source
    {
        get { return (ImageSource)GetValue(SourceProperty); }
        set { SetValue(SourceProperty, value); }
    }

    public ImageSource PlaceHolder
    {
        get { return (ImageSource)GetValue(PlaceHolderProperty); }
        set { SetValue(PlaceHolderProperty, value); }
    }

    public ImagePreview()
    {
        this.InitializeComponent();
    }

    private static void SourceChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        var control = (ImagePreview)dependencyObject;
        var newSource = (ImageSource) dependencyPropertyChangedEventArgs.NewValue;

        System.Diagnostics.Debug.WriteLine("Image source changed: {0}", ((BitmapImage)newSource).UriSource.AbsolutePath);
            

        if(newSource != null)
        {
            var image = (BitmapImage) newSource;

            // If the image is not a local resource or it was not cached
            if (image.UriSource.Scheme != "ms-appx" && image.UriSource.Scheme != "ms-resource" && (image.PixelHeight * image.PixelWidth == 0))
            {
                image.ImageOpened += (sender, args) => control.LoadImage(image);
                control.Staging.Source = image;
            }
            else
            {
                control.LoadImage(newSource);
            }
        }
    }

    private void LoadImage(ImageSource source)
    {
        ImageFadeOut.Completed += (s, e) =>
        {
            Image.Source = source;
            ImageFadeIn.Begin();
        };
        ImageFadeOut.Begin();
    }
}

Dynamic Tile Background Provider

Posted by Can Bilgin on January 24, 2013
Posted in: Live Tiles, Metro. Tagged: ASP.NET Handler, Dynamic Tile, HttpHandler, Live Tile, Tile Notifications, TileUpdateManager. 2 comments

Code Sample: Dynamic Tile Update Example with IIS Handler

To create lively-er tiles, the developers generally choose to use different web content images to send with the notification updates. Otherwise, if you want to use images from the package, they should be static content included among the package resources. This would be first of all limiting and secondly it would have an adverse effect of the package size (you might even hit the package limit if you really want to have diverse images).

When you send a tile update to windows store app client (either using the TileUpdateManager from the client itself, or using the Windows Notification Services), the tile notification content (i.e. xml content) is processed by the windows runtime and the best tile template is chosen according to the current tile used by the application. (i.e. Wide or Square).

<tile>
  <visual version="1">
    <binding template="TileWideImageAndText01">
      <image id="1" src="http://localhost:49183/Assets/TileLightWide.png" />
      <text id="1">This tile notification uses web images.</text>
    </binding>
    <binding template="TileSquareImage">
      <image id="1" src="http://localhost:49183/Assets/TileLight.png" />
    </binding>
  </visual>
</tile>

So you would have to send at least two images in a visual element to get the content right. (Notice the src attribute of the image nodes)

Left - Wide Tile Template, Right - Square Tile Template

Left – Wide Tile Template, Right – Square Tile Template

The content (i.e. the image) would normally be scaled to fit the live tile but windows runtime cannot possibly handle different aspect ratios and the rescaling of the image in most cases would give bad results. (e.g. images from news articles can be quite large, and the resulting tile would not be pleasing)

To solve this problem, you can easily implement a server side component that could pre-process the image that is to be send to the windows store app client. The meaning of “Pre-process”  can vary from selecting a static content to feed to constructing the image on the fly. The http handler would use the the parameters that are passed on by the tile update content.

In this example we will be dealing with two parameters:

1) Size: determines if the image return should be for square tile or wide tile

2) Type: determines if the background should be black or white.

So we start by creating an ASP.NET handler that will take two query parameters:

public class TileImageHandler : IHttpHandler
{
    ///
    /// You will need to configure this handler in the Web.config file of your
    /// web and register it with IIS before being able to use it. For more information
    /// see the following link: http://go.microsoft.com/?linkid=8101007

    #region IHttpHandler Members

    public bool IsReusable
    {
        // Return false in case your Managed Handler cannot be reused for another request.
        // Usually this would be false in case you have some state information preserved per request.
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        var imageType = context.Request.QueryString["type"];

        // You can essentially extend the parameters that you are using to customize the image more
        var imageSize = context.Request.QueryString["size"];

        //... Further processing
    }

    #endregion
}

These query parameters will determine what the server is going to return to client as content. In this example, we will be just reading the existing static content and pushing it to the response stream setting the content according to the parameters.

//... Image Processing

var imageSizeSuffix = imageSize == "Wide" ? imageSize : string.Empty;

var imagePath = string.Empty;

// We are using actual images to write to the stream but you can develop an image generator
// and generate the images on the fly.
switch (imageType)
{
    case "Dark":
        imagePath = context.Server.MapPath(String.Format("~/Assets/TileDark{0}.png", imageSizeSuffix));
        break;
    case"Light":
        imagePath = context.Server.MapPath(String.Format("~/Assets/TileLight{0}.png", imageSizeSuffix));
        break;
}

context.Response.ContentType = "image/png";
context.Response.StatusCode = 200;

context.Response.WriteFile(imagePath);

//...

The next step is to prepare the web.config file so the calls for a specific piece of content will be handled by our handler.

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
    
        <!-- For classic application pool -->
        <!--<httpHandlers>
            <add verb="*" path="SquareTile.png" 
                type="TileProvider.TileImageHandler, TileProvider "/>
        </httpHandlers>-->
    </system.web>
    <system.webServer>
        <handlers>
            <add name="TileHandler" verb="*" path="SquareTile.png" 
                type="TileProvider.TileImageHandler, TileProvider "/>
        </handlers>
    </system.webServer>
</configuration>

And finally we implement the tile update manager function that prepares the visual with the desired parameters.

private void SendTileUpdate(string type)
{
    // Note: This sample contains an additional project, NotificationsExtensions.
    // NotificationsExtensions exposes an object model for creating notifications, but you can also
    // modify the strings directly. See UpdateTileWithWebImageWithStringManipulation_Click for an example

    // Create notification content based on a visual template.
    ITileWideImageAndText01 tileContent = TileContentFactory.CreateTileWideImageAndText01();

    tileContent.TextCaptionWrap.Text = "This tile notification uses web images.";

    // !Important!
    // The Internet (Client) capability must be checked in the manifest in the Capabilities tab
    // to display web images in tiles (either the http:// or https:// protocols)

    tileContent.Image.Src = string.Format("http://localhost:49183/SquareTile.png?type={0}&size=Wide", type);
    tileContent.AddImageQuery = false;

    // Users can resize tiles to square or wide.
    // Apps can choose to include only square assets (meaning the app's tile can never be wide), or
    // include both wide and square assets (the user can resize the tile to square or wide).
    // Apps cannot include only wide assets.

    // Apps that support being wide should include square tile notifications since users
    // determine the size of the tile.

    // Create square notification content based on a visual template.
    ITileSquareImage squareContent = TileContentFactory.CreateTileSquareImage();

    squareContent.Image.Src = string.Format("http://localhost:49183/SquareTile.png?type={0}", type);
    squareContent.AddImageQuery = false;

    // include the square template.
    tileContent.SquareContent = squareContent;

    // send the notification to the app's application tile
    TileUpdateManager.CreateTileUpdaterForApplication().Update(tileContent.CreateNotification());

    OutputTextBlock.Text = CleanPrint(tileContent.GetContent());
}

And this is it, we have an asp.net handler that provides tile backgrounds for the metro app using different parameters.

Happy coding everyone…

Simple AES (Symmetric Key) Encryption in WinRT

Posted by Can Bilgin on October 3, 2012
Posted in: Cryptography, Metro, WinRT. Tagged: AES, CryptographicEngine, Cryptography, Encryption, Metro, Symmetric Key Algrorithm, Windows 8, WinRT. 6 comments

Symmetric key encryption, also called secret key encryption, requires that the key used for encryption also be used for decryption. You can use a SymmetricKeyAlgorithmProvider object to specify a symmetric algorithm and create or import a key. You can use static methods on the CryptographicEngine class to encrypt and decrypt data by using the algorithm and key.

Under normal circumstances on top of the encryption key used, you would need to send vector values which is used as the initialization vector. However, for a simple scenario (e.g. you want to send a password value from the client to the server or vice-versa, and you don’t want to do a post with clear-text). You wouldn’t go through the trouble of carrying the IV buffer to the client side as well.

So here is a simple implementation that uses the AES encryption with ECB cipher mode and PKCS7 padding (PKCS #7 algorithms automatically pads the message to an appropriate length, so you don’t need to pad the cipher to a multiple of the block-size of the encryption algorithm you are using)

First step is to implement an MD5 hash generator which will be use to compute a hash from the encryption key that is being used.

private static IBuffer GetMD5Hash(string key)
{
    // Convert the message string to binary data.
    IBuffer buffUtf8Msg = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);

    // Create a HashAlgorithmProvider object.
    HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);

    // Hash the message.
    IBuffer buffHash = objAlgProv.HashData(buffUtf8Msg);

    // Verify that the hash length equals the length specified for the algorithm.
    if (buffHash.Length != objAlgProv.HashLength)
    {
        throw new Exception("There was an error creating the hash");
    }

    return buffHash;
}

Once the key material is ready to be used to generate the symmetric key, we can go on with the encryption.

/// <summary>
/// Encrypt a string using dual encryption method. Returns an encrypted text.
/// </summary>
/// <param name="toEncrypt">String to be encrypted</param>
/// <param name="key">Unique key for encryption/decryption</param>m>
/// <returns>Returns encrypted string.</returns>
public static string Encrypt(string toEncrypt, string key)
{
    try
    {
        // Get the MD5 key hash (you can as well use the binary of the key string)
        var keyHash = GetMD5Hash(key);

        // Create a buffer that contains the encoded message to be encrypted.
        var toDecryptBuffer = CryptographicBuffer.ConvertStringToBinary(toEncrypt, BinaryStringEncoding.Utf8);

        // Open a symmetric algorithm provider for the specified algorithm.
        var aes = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);

        // Create a symmetric key.
        var symetricKey = aes.CreateSymmetricKey(keyHash);

        // The input key must be securely shared between the sender of the cryptic message
        // and the recipient. The initialization vector must also be shared but does not
        // need to be shared in a secure manner. If the sender encodes a message string
        // to a buffer, the binary encoding method must also be shared with the recipient.
        var buffEncrypted = CryptographicEngine.Encrypt(symetricKey, toDecryptBuffer, null);

        // Convert the encrypted buffer to a string (for display).
        // We are using Base64 to convert bytes to string since you might get unmatched characters
        // in the encrypted buffer that we cannot convert to string with UTF8.
        var strEncrypted = CryptographicBuffer.EncodeToBase64String(buffEncrypted);

        return strEncrypted;
    }
    catch (Exception ex)
    {
        // MetroEventSource.Log.Error(ex.Message);
        return "";
    }
}

The decryption function is not any different in this case except for the fact that you would need to use Base64 conversion to convert the encrypted cipher to a buffer.

/// <summary>
/// Decrypt a string using dual encryption method. Return a Decrypted clear string
/// </summary>
/// <param name="cipherString">Encrypted string</param>
/// <param name="key">Unique key for encryption/decryption</param>
/// <returns>Returns decrypted text.</returns>
public static string Decrypt(string cipherString, string key)
{
    try
    {
        // Get the MD5 key hash (you can as well use the binary of the key string)
        var keyHash = GetMD5Hash(key);

        // Create a buffer that contains the encoded message to be decrypted.
        IBuffer toDecryptBuffer = CryptographicBuffer.DecodeFromBase64String(cipherString);

        // Open a symmetric algorithm provider for the specified algorithm.
        SymmetricKeyAlgorithmProvider aes = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);

        // Create a symmetric key.
        var symetricKey = aes.CreateSymmetricKey(keyHash);

        var buffDecrypted = CryptographicEngine.Decrypt(symetricKey, toDecryptBuffer, null);

        string strDecrypted = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, buffDecrypted);

        return strDecrypted;
    }
    catch (Exception ex)
    {
        // MetroEventSource.Log.Error(ex.Message);
        //throw;
        return "";
    }
}

And there it goes, a simple symmetric key encryption ready to be used in Windows Store Apps (aka Metro).

Happy coding everyone…

Drawing / Inking API in WinRT (C#) – II

Posted by Can Bilgin on August 11, 2012
Posted in: Inking, Inking, Metro, WinRT. Tagged: Inking, InkManager, InkManager.SaveAsync, IRandomAccessStream, Load Strokes, Save Strokes. 4 comments

Code Sample: Windows 8 Input: Ink sample in C#/Xaml

In the previous part of this series, we talked about how to use efficiently the inking namespace in WinRT. As you may recall the main component in this drawing adventure was InkManager. In this part of the series, we will be talking about how we can save the strokes to an image file and later on load and render these stokes.

Saving the Ink Stokes

In WinRT API, the only function that InkManager exponses for saving strokes is the SaveAsync method. This might be quite disappointing for most since in good old silverlight, one could easily load an InkPresenter to WriteableBitmap and manupulate it as he/she wants.

try
{
    Windows.Storage.Pickers.FileSavePicker save = new Windows.Storage.Pickers.FileSavePicker();
    save.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
    save.DefaultFileExtension = “.png”;
    save.FileTypeChoices.Add(“PNG”, new string[] { “.png” });
    StorageFile filesave = await save.PickSaveFileAsync();

    using (IOutputStream fileStream = await filesave.OpenAsync(FileAccessMode.ReadWrite))
    {
        if (fileStream != null)
        {
            await m_InkManager.SaveAsync(fileStream);
        }
    }
}
catch (Exception ex)
{
    var dialog = new MessageDialog(ex.Message);
    dialog.ShowAsync();
}

In this implementation we are using a FileSavePicker to create a file, but we could as well use an InMemoryRandomAccessStream. Using the memory stream also help you to display the image in an Image control right away. (e.g. You might want to preview the image that is drawn in a smaller size.)

Loading the Ink Strokes

When the ink strokes are serialized into an image file, you as well load these strokes back to an InkManager and also use them to render the image for further editing perhaps..

using (IRandomAccessStream stream = await storageFile.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
    await m_InkManager.LoadAsync(stream);

    if (m_InkManager.GetStrokes().Count > 0)
    {
        // RenderStrokes();
    }
}

You could possibly use the same render function that was outlined on the previous article.

Further Implementation

The saving of the ink strokes creates a rectangle that is only a small cutout from the whole canvas. (e.g. Canvas.ActualWidth = InkManager.BoundingRectangle.Left + InkManager.BoundingRectangle.Width + InkManager.BoundingRectangle.Right) Still trying to figure out how to include the whole canvas area in the image that is saved.

The main reason for this cropped version of the canvas is the fact that even though we are saving the stokes to a “PNG” file (and the microsoft version uses “GIF”), the file is actually in ISF format (*.isf). You can as well rename the extension to .isf and open the image file with paint and save it as “*.png”. You will notice that the magic number change on the file binary and the file size change.

Good luck everyone, happy coding.

Drawing / Inking API in WinRT (C#) – I

Posted by Can Bilgin on July 26, 2012
Posted in: Windows 8, WinRT. Tagged: BezierSegment, Canvas, Inking, InkManager, Metro, PointerPressed, Windows 8, WinRT. 18 comments

Code Sample: Windows 8 Input: Ink sample in C#/Xaml

If you are planning to develop an application that is going to have the drawing capability, one of the first namespaces to resort to in WinRT is the Inking namespace. Using the InkManager in Windows 8 (Metro) applications, you can:

  • Draw ink strokes
  • Capture ink strokes
  • Render Strokes on a Canvas using different geometries
  • Select Strokes
  • Delete Strokes
  • Save and Load Strokes
  • Convert strokes to text through handwriting recognition
  • Copy/Paste strokes from the clipboard
  • Hit Test the pen input

In  this article, we will be talking about different methodologies for rendering the pen input on the Canvas element on Metro applications.

You can get the complete solution that will be used as the example from TechNet : Windows 8 Input: Ink sample in C#/Xaml

Rendering Pointer Movements

Maybe the easiest and the most efficient way to render the pen input is to render each pointer movement when the pointer is pressed until it is released.

For this purpose, we add a canvas element on our page:

<Grid Background=”White”>
    <Canvas Name=”InkCanvas” Background=”White” Margin=”0,0,0,0″ />
</Grid>

Let us add the pointer handlers to our page. We need two handlers for PointerPressed, PointerMoved.

public void OnCanvasPointerPressed(object sender, PointerRoutedEventArgs e)
{
    // Get information about the pointer location.
    PointerPoint pt = e.GetCurrentPoint(InkCanvas);
    m_PreviousContactPoint = pt.Position;

    // Accept input only from a pen or mouse with the left button pressed.
    PointerDeviceType pointerDevType = e.Pointer.PointerDeviceType;
    if (pointerDevType == PointerDeviceType.Pen ||
        pointerDevType == PointerDeviceType.Mouse && pt.Properties.IsLeftButtonPressed)
    {
        e.Handled = true;
    }
    else if (pointerDevType == PointerDeviceType.Touch)
    {
        // Process touch input
    }
}

When the user presses the pointer or uses the Ink Pen, we just record the starting point (m_PreviousContactPoint) to use.

Then when the pointer moves, we assume that the user is trying to draw something on the canvas:

public void OnCanvasPointerMoved(object sender, PointerRoutedEventArgs e)
{
    if (e.Pointer.PointerId == m_PenId)
    {
        PointerPoint pt = e.GetCurrentPoint(InkCanvas);

        currentContactPt = pt.Position;
        x1 = m_PreviousContactPoint.X;
        y1 = m_PreviousContactPoint.Y;
        x2 = currentContactPt.X;
        y2 = currentContactPt.Y;

        var color = m_CurrentDrawingColor;
        var size = m_CurrentDrawingSize;

        if (CalculateDistance(x1, y1, x2, y2) > 2.0)
        {
            //
            // If the delta of the mouse is significant enough,
            // we add a line geometry to the Canvas
            Line line = new Line()
            {
                X1 = x1,
                Y1 = y1,
                X2 = x2,
                Y2 = y2,
                StrokeThickness = size,
                Stroke = new SolidColorBrush(color)
            };

            m_PreviousContactPoint = currentContactPt;

           // Draw the line on the canvas by adding the Line object as
           // a child of the Canvas object.
           InkCanvas.Children.Add(line);
        }
    }
    else if (e.Pointer.PointerId == m_TouchId)
    {
        // Process touch input
    }
}

And for the PointerReleased, we just set e.Handled to true.

At this point we already have an example that can draw images and of which you can adjust the size and the color of the drawn lines.

But what if you want to use some more advanced functions such as hand writing recognition or copy/paste and save/load functionality. For these options, it is better to use InkManager and render the strokes that the InkManager records.

Rendering Strokes from InkManager

For the InkManager to be able to record the strokes, we need to pass on the pointer events to the InkManager.

In the PointerPressed event handler:

// (Already have) PointerPoint pt = e.GetCurrentPoint(InkCanvas);

// Pass the pointer information to the InkManager.
CurrentManager.ProcessPointerDown(pt);

In the PointerMoved event handler:

// Pass the pointer information to the InkManager.
CurrentManager.ProcessPointerUpdate(pt);

In the PointerReleased event handler:

// Pass the pointer information to the InkManager.
CurrentManager.ProcessPointerUp(pt);

S0 once we are recording the movements of the pointer, the InkManager will create a list of strokes for us to use to render.

You can render each stroke using a BezierSegment and a PathFigureCollection.

private void RenderStroke(InkStroke stroke, Color color, double width, double opacity = 1)
{
    // Each stroke might have more than one segments
    var renderingStrokes = stroke.GetRenderingSegments();

    //
    // Set up the Path to insert the segments
    var path = new Windows.UI.Xaml.Shapes.Path();
    path.Data = new PathGeometry();
    ((PathGeometry)path.Data).Figures = new PathFigureCollection();

    var pathFigure = new PathFigure();
    pathFigure.StartPoint = renderingStrokes.First().Position;
    ((PathGeometry)path.Data).Figures.Add(pathFigure);

    //
    // Foreach segment, we add a BezierSegment
    foreach (var renderStroke in renderingStrokes)
    {
        pathFigure.Segments.Add(new BezierSegment()
        {
            Point1 = renderStroke.BezierControlPoint1,
            Point2 = renderStroke.BezierControlPoint2,
            Point3 = renderStroke.Position
        });
    }

    // Set the general options (i.e. Width and Color)
    path.StrokeThickness = width;
    path.Stroke = new SolidColorBrush(color);

    // Opacity is used for highlighter
    path.Opacity = opacity;

    InkCanvas.Children.Add(path);
}

You can retrieve a list of strokes by calling the GetStrokes method of the InkManager.

Further Implementation

To create a complete implementation, you can create a Refresh method which would remove the Line elements that are added while the user is still moving the pointer and only render the strokes from the InkManager.

The refresh method would then be called when the user releases the pointer and the temporary paths that are drawn during the action are replaced by the BezierSegments.

You can continue the second part where we discuss the loading and saving of the Ink Strokes here: Drawing / Inking API in WinRT (C#) – II

 

BitmapImage Set Source Asynchronously

Posted by Can Bilgin on June 18, 2012
Posted in: Metro, Task, Threading, Windows 8, WinRT. Tagged: BitmapImage, SetSource, SetSourceAsync, Task, TaskCompletionSource, Threading. 4 comments

Following an MSDN post, I was investigating the BitmapImage usage patterns in WinRT. When you want to use the image properties after setting the stream as the source for your BitmapImage, you normally have to write an event handler that will execute on ImageOpened. Or a fail scenario, when the image does not load when you are setting the URL. However, going for an observer pattern rather than using the asynchronous task pattern in metro seemed a bit odd.

However thanks to the TaskCompletionSource, one can easily “convert” an event dependent function to an awaitable Task implementation.

Here is the extension method implementation that lets you wait for image to be set as source and continue with your execution.

public static class BitmapImageExtensions
{
    public static Task<bool> SetSourceAsync(this BitmapImage image, IRandomAccessStream stream)
    {
        var tcs = new TaskCompletionSource<bool>();

        image.ImageOpened += (o, e) =>;
        {
            tcs.SetResult(true);
        };

        image.ImageFailed += (o, e) =>;
        {
            tcs.SetResult(false);
        };

        image.SetSource(stream);

        return tcs.Task;
    }
}

And the usage of this function would look something like:

IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read);
BitmapImage bitmapImage = new BitmapImage();

if (await bitmapImage.SetSourceAsync(stream))
{

    Debug.WriteLine("width: {0}, height: {1}", bitmapImage.PixelWidth, bitmapImage.PixelHeight);

}

Hoping that it helps someone out there.

UPDATE: As it seems (thanks for the info mamorus), this specific functionality with the addition of CancellationToken was added to RTM release. (Refer to: BitmapSource.SetSourceAsync(IRandomAccessStream) )

Posts navigation

← Older Entries
  • Can Bilgin

    Can Bilgin

    Can Bilgin works in CompuSight Corp as a Senior Software Architect. He has been working in software industry with Microsoft technologies for over 8 years. In this period he took key roles in projects for high profile clients such as Microsoft, General Electric, Raiffeisen Bank, Jettainer and Adobe Echosign using technologies such as BizTalk, SharePoint, InfoPath, Windows Mobile, Windows Phone, WinRT and WCF.

    His team recently received the Best Productivity App Award from Windows Store Application Contest by Qualcom.

  • Recent Posts

    • Async Development in WinRT – I
    • Image UserControl with FadeIn & FadeOut Animation for WinRT
    • Dynamic Tile Background Provider
    • Simple AES (Symmetric Key) Encryption in WinRT
    • Drawing / Inking API in WinRT (C#) – II
  • Archives

    • May 2013
    • January 2013
    • October 2012
    • August 2012
    • July 2012
    • June 2012
    • April 2011
    • June 2010
  • Categories

    • CRM
    • Cryptography
    • DataContractJsonSerializer
    • DataContractSerializer
    • Inking
    • Inking
    • IRandomAccessStream
    • Live Tiles
    • Metro
    • Microsoft Dynamics CRM
    • oData
    • REST
    • Serialization
    • Task
    • Threading
    • Transitions
    • Uncategorized
    • WCF
    • Windows 8
    • WinRT
  • Meta

    • Register
    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.com
Blog at WordPress.com. Theme: Parament by Automattic.
Can Bilgin
Blog at WordPress.com. Theme: Parament.
Follow

Get every new post delivered to your Inbox.

Powered by WordPress.com
Cancel