TAP versus EAP

In Windows Phone 7 waren alle async methods via het event asynchronous pattern wat wil zeggen een method waarmee je de actie start en een event wanneer de operatie compleet is. Je ziet dit bijvoorbeeld op de webclient waar je een dergelijke schrijf wijze zou kunnen gebruiken:

public void GetUrl()
        {
            WebClient client = new WebClient();
            client.DownloadStringCompleted += (s, e) =>
                {
                } ;
            client.DownloadStringAsync(new Uri("http://bing.com"))
        }

Met de release van Windows 8 en de nieuwe C# heeft Microsoft de taal C# uitgebreid met 2 nieuwe keywords die ook een nieuwe async pattern "Task Async Pattern" mogelijk maakt. Dit maakt async programmeren veel eenvoudiger, en dat is ook terug te zien in het platform, aanzienlijk meer API's zijn async geworden. Met TAP komt het er zo uit te zien:

public async void GetUrl()
{
    HttpClient client = new HttpClient();
    using (var data = await client.GetStreamAsync(url))
    {
    }
}

De code wijkt vrijwel niet af van wanneer het niet async zou gebeuren behalve het gebruik van async en await keyword. Het is wel async en vraagt nog wel extra aandacht maar dat laat ik hier even buiten beschouwing.

In Windows Phone 8 is Microsoft niet opnieuw begonnen maar zijn er wel heel veel features uit Windows 8 over geheveld naar de Phone, maar ook heel veel API's zo als deze op Windows Phone 7 bestonden. Voor het asynchroon werken betekend het dat we nu gebruik moeten maken van 2 patronen door elkaar, wat ik zelf niet duidelijker op vind worden.

Gelukkig is het eenvoudig om EAP patroon te wrappen in een een TAP versie . Bij deze de oplossing hoe ik het voor de webclient heb gedaan:

public static class WebClientExtensions
    {
        public static Task<string> DownloadStringAsyncTask(this WebClient client, Uri address)
        {
            TaskCompletionSource<string> completionSource = new TaskCompletionSource<string>();
            client.DownloadStringCompleted += client_DownloadStringCompleted;
            client.DownloadStringAsync(address, completionSource);
            return completionSource.Task;
        }

        private static void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            WebClient client = (WebClient)sender;
            TaskCompletionSource<string> completionSource = (TaskCompletionSource<string>)e.UserState;

            client.DownloadStringCompleted -= client_DownloadStringCompleted;
            try
            {
                completionSource.SetResult(e.Result);
            }
            catch(Exception ex)
            {
                completionSource.SetException(ex);
            }
        }
    }

 

  •   RT @VisualStudio: In this episode, we're joined by Kasey Uhlenhuth (@kuhlenhuth) who shows some of the refactoring features available in Vi…
  •   @VSTS problems with build queues atm?
  •   RT @donasarkar: Hi #WindowsInsiders we have released Build 17713 to the Fast ring! This build has several new features we think IT Pros wil…
  •   RT @maryjofoley: ICYMI, another Windows 10 on ARM PC is available: Lenovo Miix 630 ARM-based 2-in-1 Windows tablet goes on sale for $900 ht…
  •   the moment you have a meeting and skype for business protocol handller is lost again ...
  •   @LocalJoost Surface Go vanaf 27 augustus te bestellen?
  •   tnx @VistaHypotheken https://t.co/qFoQS6mQ63
  •   @gotheap based on the link i understand they should show up after a build as well? i only see them for the test on… https://t.co/XadwWJjIAM
  •   @panos_panay will the surface go with lte have gps? i need a new device to run my own app for navigation while flying around
  •   @aaronbjork @IoannisKarlis @Jira @VSTS and replace delivery plans with the feature timeline extension. that is really helpful!