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 @alvinashcraft: Getting Started with Lottie-Windows. #xaml #winui #uwp #windowsdev https://t.co/P4EWilrffA
  •   RT @WindowsUI: We are releasing new samples and documentation today showing how to use the compositor's Visual Layer APIs in win32 apps: ht…
  •   RT @JenMsft: @PXAbstraction With the latest version of W10, you can now tie snipping to PrintScreen - lets you capture things that would ot…
  •   RT @JenMsft: It was so fun to talk to the MVPs today about [REDACTED] 😁 #MVPSummit #MVPBuzz
  •   RT @JenMsft: New build for Fast! Look for 18361 - let us know how it goes once you upgrade! Details here: https://t.co/KCrMGkCsCY 😊 #Window…
  •   @JenMsft Plqn to visit 33?
  •   RT @JenMsft: Image support now rolling out for Sticky Notes if you're in Skip Ahead 😊 #WindowsInsiders Details 👉🏻 https://t.co/6IAdzNYeIs…
  •   RT @ClintRutkas: having a great time discussing Windows Development topics at the #mvpSummit. If you feel a community member is a Microsof…
  •   @NicoVermeir revenge is sweet 🤣
  •   @theothernt found a whole dutch delegation at 4am @ starbucks :)