Threads vs Tasks

Laatste tijd ben ik veel actief op het Windows Store forum op MSDN en kwam ik een leuke vraag tegen.

Er was het volgende stuk code en de vraagsteller verwachtte dezelfde uitkomst maar kreeg een verschil.

/// <summary>
        /// A1/A3/A4/A9
        /// </summary>
        private async void Button_Click_1(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("A1");
            await ThreadPool.RunAsync((operation) => { DoOperation("A").Wait(); }, WorkItemPriority.Normal);
            Debug.WriteLine("A9");
        }
        /// <summary>
        /// B1/B3/B9/B4
        /// </summary>
        private async void Button_Click_2(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("B1");
            await ThreadPool.RunAsync(async (operation) => await DoOperation("B"), WorkItemPriority.Normal);
            Debug.WriteLine("B9");
        }
        private async Task DoOperation(string s)
        {
            Debug.WriteLine("{0}3", s);
            await Task.Delay(1);
            Debug.WriteLine("{0}4", s);
        }

 

Button_Click_1 geeft natuurlijk netjes A1, A3, A4, A9 omdat await ThreadPool zal blijven wachten tot de thread eindigt. Button_Click_2 eindigd de thread al na het printen van B3 en zal B9 dus voor B4 worden geprint. Dit maakt meteen mooi het verschil tussen Wait() en het keyword Await duidelijk. Wait blokkeert de thread terwijl await juist niet blokkeert alleen het werk later opnieuw inscheduled, waardoor dus de thread endigt in geval van Button_Click_2 voordat B4 is aangeroepen.

In de bovenstaande geval is met ouderwetse threadpool gewerkt en wanneer die word vervangen door Tasks komt er weer iets opmerkelijks:

private async void Button_Click_3(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine("T1");
            await Task.Run(async () => await DoOperation("T"));
            Debug.WriteLine("T9");
        }

In dit voorbeeld word dezelfde aanpak als in Button_Click_2 gebruikt enkel is de threadpool door een task vervangen. De uitkomst is echter niet gelijk aan die van 2 maar aan die van 1, T1, T3, T4 T9. Tasks zijn geen Threads, en dat word hier erg goed helder. De Task word netjes afgewacht voordat de Task van Task.Run eindigd en T9 word geprint. 

Link naar de orginele post: http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/161bdd6c-74a5-485d-8293-63c18afd9dd2/#2c2f49c0-083c-4969-9520-20f0bae5172f

  •   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 :)