Mini Recorder updated to 1.2

Posted on Jun 28, 2012 in and tagged ,

Mini Recorder, a minimalistic digital audio recorder for Windows Phone have been updated to version 1.2.

While there are no new features in this release, it brings several hot fixes reported by users. Especially, the major one that caused compression settings not being applied when uploading files to Dropbox.

Go grab it at the marketplace for free!

Silverlight Unit Testing NuGet package

Posted on Jun 26, 2012 in and tagged ,
Silverlight Toolkit has several NuGet packages (Core, Input, Theming, etc.). Unfortunately, Unit Testing Framework, which comes as a part of downloadable toolkit version, was not available for the fellow NuGet users. Until now. You can easily install it by typing ‘Install-Package SilverlightToolkit-Testing’ in the Package Manager console. Details here. The package just adds references to Microsoft.Silverlight.Testing.dll and Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight.dll assemblies, so that you don’t have to install toolkit or bloat your VCS with unnecessary binaries.

Microsoft has recently announced the line-up of Visual Studio 11 products. And it seems that the next Visual Studio Express edition is going to support only a subset of target platforms – Windows 8 Metro, Windows Phone, Web and Azure. If that’s the case, then you won’t be able to build regular desktop apps (from console to WPF) with the starter edition pack. That’s right, you need to buy a $500 product to create a basic console app. It’s unclear whether the SDK and compiler tools will be freely available or not (that’s how it works now – you install .NET Framework SDK and get a bare C# compiler for free).

Obviously, the community got really disappointed. However, there is a small chance to convince Microsoft that they need to change their licensing policy – you can vote for the new ticket at Visual Studio UserVoice forum (its name is weird and mentions C++ only, should be more generic IMO). It already got more than thousand votes in a few days. Note: while there are a bunch of haters in the comments, you can also find some valid points, like developing the open-source libraries scenarios. So go ahead and express your opinion.

Papercut updated to 1.1

Posted on May 25, 2012 in and tagged ,

The first update for Papercut has been certified yesterday and it should appear in the marketplace within 24 hours. For those of you who doesn’t know what Papercut is – it’s a small Windows Phone tool that allows you to get daily Bing photos (those awesome ones that you see on the search page) right on your phone. There is a nice video demo on Youtube.

The biggest issue that many users reported since 1.0 was the app crashing sometimes when downloading photos. This should be fixed now, however, the photos will not be grouped by countries for those users. Basically, this behavior is caused by the way the Bing images endpoint works – it relies on HTTP headers to transfer important image information, especially on ETag that works like an image hash. This ETag header is used as an image grouping key, so if there is no header in the server’s response, then the grouping is not possible.

There are several ways to solve this issue, I am trying to figure out the best one now.

Anyway, let’s get back to the topic. Here is the full changelog for version 1.1:

  • Fixed issues with background task crashing.
  • Fixed issue when application crashed during image loading.
  • Increased image quality with support for 32 bits color mode (right, the gorgeous images should look even more awesome now).
  • Added image loading animations.
  • Trial mode check is delayed to reduce startup time.
  • Fullscreen images are shown and hidden much faster now (it was really painful with 1.0 – going back from image view to the previous page took almost a second on my old Omnia 7, now it’s almost instant).

You can download the free version here.
If you want to support me, there is also a paid version here.

Get daily Bing images with Papercut

Posted on May 20, 2012 in and tagged ,

Papercut is a new app that lets you use photos from the Bing homepage as the background of your phone’s lock screen. It’s fast and easy to use, all powered by Metro UI goodness.

It also gives you a great Live Tile that shows the latest photo right on your start screen. Each image has a short headline with its description (it’s always great to learn new things, right?) – just tap the photo when it is loaded.

The best thing is that Papercut is absolutely free to use, withoud ads (but if you want to support the developer and donate 99 cents, there is a paid version in the marketplace). Enjoy!

Download FREE version here and the paid version here.

You can also follow @PapercutWP on Twitter.

Every time I create a new app, I have to spend at least 10-15 minutes just to remove all the clutter that the guys who created them put in. Probably they thought than an average developer won’t be smart enough to figure out that THIS IS APPLICATION TITLE, DUDE!!1 And why do you need a backing field for each and every control on the page? Arrgh.

My favorite is that vital ‘phoneApplicationInitialized‘ variable. Just, look at this code (I’ve changed the order of class members and removed some unrelated calls, but that doesn’t matter):

private bool phoneApplicationInitialized = false;
 
public App()
{
    InitializeComponent();
    InitializePhoneApplication();
}
 
private void InitializePhoneApplication()
{
    if (phoneApplicationInitialized)
        return;
 
    RootFrame = new PhoneApplicationFrame();
    RootFrame.Navigated += CompleteInitializePhoneApplication;
    RootFrame.NavigationFailed += OnNavigationFailed;
 
    // Ensure we don't initialize again
    phoneApplicationInitialized = true;
}

So its value is modified only inside InitializePhoneApplication method that is called only from the class constructor. That first condition check never returns and there is no way to ‘initialize again’.

Anyway, I decided to create my own reusable page and application definition templates to save some time. Obviously, they may not suit your needs, so think about them as a reference or an alternative to the predefined templates.

App template

<Application
    x:Class="$namespace$.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:system="clr-namespace:System;assembly=mscorlib"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">

    <Application.Resources>
        <system:String x:Key="ApplicationTitle">APPLICATION TITLE</system:String>
        
        <!-- Page margins -->
        <Thickness x:Key="PageHeaderPanelMargin">12,17,0,28</Thickness>
        <Thickness x:Key="PageNameLabelMargin">9,-7,0,0</Thickness>
        <Thickness x:Key="PageContentPanelMargin">12,0</Thickness>
        
        <Style x:Key="DefaultPageStyle" TargetType="phone:PhoneApplicationPage">
            <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
            <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeNormal}"/>
            <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
            <Setter Property="SupportedOrientations" Value="Portrait"/>
            <Setter Property="Orientation" Value="PortraitUp"/>
            <Setter Property="shell:SystemTray.IsVisible" Value="True"/>
        </Style>
    </Application.Resources>
    
    <Application.ApplicationLifetimeObjects>
        <shell:PhoneApplicationService />
    </Application.ApplicationLifetimeObjects>
</Application>

Page template

    <phone:PhoneApplicationPage
    x:Class="$namespace$.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Style="{StaticResource DefaultPageStyle}"
    mc:Ignorable="d"
    d:DesignHeight="800"
    d:DesignWidth="480">

    <Grid Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel Margin="{StaticResource PageHeaderPanelMargin}">
            <TextBlock
                Text="{StaticResource ApplicationTitle}"
                Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock
                Text="page name"
                Margin="{StaticResource PageNameLabelMargin}"
                Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <Grid
            Grid.Row="1"
            Margin="{StaticResource PageContentPanelMargin}">
            
        </Grid>
    </Grid>
</phone:PhoneApplicationPage>

You can also download zipped templates ready for importing into Visual Studio.
Just place them into “%my_docs%Visual Studio TemplatesItemTemplatesSilverlight for Windows Phone”.

Application and Page

Async sequential workflows

Posted on Apr 26, 2012 in and tagged ,

В последнее время всё чаще приходится сталкиваться с задачами, требующими выполнения последовательных асинхронных операций. Примером может служить загрузка файлов на мобильном устройстве. Учитывая что телефон может работать на слабом мобильном соединении, нам вряд ли удастся получить прирост производительности от параллельной загрузки. Да и стандартный класс WebClient, представленный в BCL не очень дружит с concurrent operations (точнее вообще не дружит). Создавать новый экземпляр на каждый запрос кажется идейно неправильным, так что попробуем обойтись одним веб-клиентом, обрабатывающим множество последовательных запросов.

Для начала – тривиальная синхронная реализация (которая конечно же не будет работать на WP7 из-за отсутствия синхронных методов у WebClient‘а):

public IEnumerable<string> Handle(IEnumerable<Uri> requests)
{
    var client = new WebClient();
 
    foreach (var request in requests)
    {
        yield return client.DownloadString(request);
    }
}

Разработчику, использующему асинхронную версии, скорее всего захочется узнать о моменте завершении загрузок. Не будем плохими мальчиками/девочками и отбросим мысли о EAP и ручном CPS. Довольно очевидным решением будет представить наши ожидающие загрузки файлы в виде потока событий при помощи observables. К сожалению, WebClient использует EAP для своих асинхронных операций, поэтому код становится чуть более неопрятным:

public IObservable<string> HandleAsync(IList<Uri> requests)
{
    var client = new WebClient();
    var subject = new Subject<string>();
    var enumerator = requests.GetEnumerator();
 
    
    Action takeNext = () =>
    {
        if (enumerator.MoveNext())
        {
            client.DownloadStringAsync(enumerator.Current);
        }
        else
        {
            subject.OnCompleted();
        }
    };
 
    client.DownloadStringCompleted += (s, e) =>
    {
        if (e.Error != null)
        {
            subject.OnError(e.Error);
        }
        else
        {
            subject.OnNext(e.Result);
            takeNext();
        }
    };
 
    takeNext();
 
    return subject;
}

В обоих случаях мы по сути описываем корутины, передающие управление в момент окончания обработки запроса. В синхронной реализации компилятор разворачивает yield в конечный автомат, генерирующий поток ответов, в асинхронной мы создаём его самостоятельно через замыкание на enumerator и итерацию внутри обработчика события DownloadStringCompleted. Те, кто уже использует async/await, могут переложить часть забот по описанию автомата на компилятор:

public async void HandleTaskAsync(IList<Uri> requests, Action<IObservable<string>> setObservable)
{
    var subject = new Subject();
    setObservable(subject);
 
    var client = new WebClient();
 
    foreach (var request in requests)
    {
        var response = await client.DownloadStringTaskAsync(request);
        subject.OnNext(response);
    }
}

Однако и в этом случае не обошлось без некоторых костылей – чтобы передать observable вызывающему методу, приходится использовать дополнительный параметр Action. Можно было бы воспользоваться интерфейсом IProgress, но для целостности будем рассматривать только IObservable.

Можно заметить, что на самом деле все эти 3 реализации очень похожи и отличаются лишь способом вызова континуаций (на следующей кликабельной картинке одинаковыми цветами отмечены аналогичные участки кода для каждого варианта).

Вернёмся к нашей асинхронной реализации с использованием observables. Хотелось бы всё-таки сделать её более обобщённой чтобы мы могли использовать использовать её подобно другим функциям высшего порядка из ObservableExtensions. Если ограничиться только EAP, то у любой задачи с последовательными асинхронными операциями есть:

  • функция run: T -> unit, запускающая операцию для очередного элемента входной последовательности
  • событие окончания выполнения операции completed: (object * TEventArgs) -> unit
  • параметрический тип TEventArgs, как правило содержащий информацию о результате выполнения операции или о произошедшей ошибке

Следовательно, можно написать следующую функцию:

public static IObservable<TResult> SelectFromAsyncEventPattern
    <TSource, TResult, TDelegate, TEventArgs>(
    this IEnumerable<TSource> source,
    Action<TSource> run,
    Func<EventHandler<TEventArgs>, TDelegate> conversion,
    Action<TDelegate> subscribe,
    Action<TDelegate> unsubscribe,
    Func<TEventArgs, TResult> mapResult,
    Func<TEventArgs, Exception> mapException)
 
    where TEventArgs: EventArgs
{
    var enumerator = source.GetEnumerator();
    var subject = new Subject<TResult>();
    var convertedHandler = default(TDelegate);
 
    Action takeNext = () =>
    {
        if (enumerator.MoveNext())
        {
            run(enumerator.Current);
        }
        else
        {
            subject.OnCompleted();
            unsubscribe(convertedHandler);
        }
    };
 
    EventHandler<TEventArgs> handler = (s, e) =>
    {
        var exception = mapException(e);
        if (exception != null)
        {
            subject.OnError(exception);
            unsubscribe(convertedHandler);
        }
        else
        {
            var result = mapResult(e);
            subject.OnNext(result);
            takeNext();
        }
    };
 
    convertedHandler = conversion(handler);
    subscribe(convertedHandler);
 
    takeNext();
    return subject;
}

На первый взгляд сигнатура может показаться не очень понятной и дружелюбной. В частности, пришлось ввести ещё один параметрический тип TDelegate и параметры conversion, subscribe и unsubscribe для обобщения события завершения операции (подобно методу Observable.FromEventPattern из Rx). В остальном код практически идентичен изначальной асинхронной реализации – подписываемся на событие, при каждом срабатывании сообщаем подписчикам о новом значении, аналогично уведомляем их при ошибке или после обработки всех элементов входной последовательности.

Пример использования:

public IObservable<string> HandleAsync(IList<Uri> requests)
{
    var client = new WebClient();
 
    return requests.SelectFromAsyncEventPattern
        <Uri, string, DownloadStringCompletedEventHandler,
            DownloadStringCompletedEventArgs>(
        client.DownloadStringAsync,
        handler => (s, e) => handler(s, e),
        x => client.DownloadStringCompleted += x,
        x => client.DownloadStringCompleted -= x,
        x => x.Result,
        x => x.Error);
}

К сожалению, компилятору не удаётся выполнить автоматический вывод типов, поэтому приходится указывать их вручную. Однако такой код всё равно выглядит лучше множественных вложенных континуаций.

Посмотреть и скачать примеры кода можно на Bitbucket.

How to generate error log from nested exceptions.

Posted on Apr 24, 2012 in and tagged

Working on error logging for my new application I’ve realized that I always use the same pattern when it comes to converting actual exceptions into a text form. And since I started posting rare code snippets that I write down all the time on Gist recently, there will be a number of ‘sharing code’ blog posts in the foreseeable future.

The code is rather simple, it traverses down the entire nested exception hierarchy and populates StringBuilder with the appropriate error information. There is a slightly different workflow for AggregateException – we want to flatten its InnerExceptions collection.

public string GetExceptionLog(Exception exception)
{
    return UnwrapExceptionTextLoop(new StringBuilder(), 0, exception);
}

private string UnwrapExceptionTextLoop(StringBuilder sb, int level, Exception e)
{
    if (e == null)
    {
        return sb.ToString();
    }

    for (int i = 0; i < level; i++)
    {
        sb.Append(">>");
    }

    var aggregate = e as AggregateException;

    sb.AppendFormat("{0} - {1} [{2}] {3}", e.GetType(), aggregate == null ? e.Message : String.Empty, e.StackTrace, Environment.NewLine);

    if (aggregate != null)
    {
        return String.Join(Environment.NewLine,
            aggregate.InnerExceptions.Select(inner => UnwrapExceptionTextLoop(sb, level + 1, inner)));
    }

    return UnwrapExceptionTextLoop(sb, level + 1, e.InnerException);
}

Let’s put on a simple method that throws several exceptions:

public void TestMethod()
{
    try
    {
        try
        {
            throw new Exception("Inner exception");
        }
        catch (Exception ex)
        {
            throw new Exception("Outer exception");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ErrorHelper.GetExceptionLog(ex));
    }
}

And here is the result (I’ve omitted the large stack trace information):

System.Exception - Outer exception [   at Client.App.TestMethod()..] 
>>System.Exception - Inner exception [   at Client.App.TestMethod()..]

Pretty straightforward, but just in case.. Here is the snippet:

SharpZipLib for WP7 NuGet package

Posted on Apr 16, 2012 in and tagged ,

I really got used to NuGet in the last year and I have almost completely forgotten what is ‘manually adding library file reference’ (can’t say I regret about that). So I was a bit disappointed when I found out that the well-known SharpZipLib NuGet package can’t be used with WP7 projects. However, there is a nice SL/WP7 port version of this library on codeplex (seems that it is abandoned though – no updates in ~2 years, but it works). It was not available to the fellow NuGetters.. until now. Use

Install-Package SharpZipLib-WP7

There is also a package mirror at BitBucket. Happy zipping!