Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

00s called, they want their C# back... :P

        private async void Button_Click(object sender, EventArgs e)
        {
            label1.Text = "Whatewer";
            await Task.Delay(1000);
            label1.Text = string.Empty;
        }
Look ma no threads!

 

<Window x:Class="wpfAnimations.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Label Name="lblTest" Margin="10,10,10,10">
            <Label.Triggers>
                <EventTrigger RoutedEvent="MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <StringAnimationUsingKeyFrames
                                Storyboard.TargetName="lblTest"
                                Storyboard.TargetProperty="Content"
                                Duration="0:0:1">
                                <StringKeyFrameCollection>
                                    <DiscreteStringKeyFrame Value="This"></DiscreteStringKeyFrame>
                                    <DiscreteStringKeyFrame Value="This is" />
                                    <DiscreteStringKeyFrame Value="This is a" />
                                    <DiscreteStringKeyFrame Value="This is a test" />
                                    <DiscreteStringKeyFrame Value="This is a test string" />
                                </StringKeyFrameCollection>
                            </StringAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="MouseLeave">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation
                                Storyboard.TargetName="lblTest"
                                Storyboard.TargetProperty="Opacity"
                                From="1.0"
                                To="0.0"
                                Duration="0:0:1"
                                FillBehavior="Stop"></DoubleAnimation>
                            <StringAnimationUsingKeyFrames
                                Storyboard.TargetName="lblTest"
                                Storyboard.TargetProperty="Content"
                                Duration="0:0:0"
                                BeginTime="0:0:1">
                                <StringKeyFrameCollection>
                                    <DiscreteStringKeyFrame Value=""/>
                                </StringKeyFrameCollection>
                            </StringAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Label.Triggers>
        </Label>

    </Grid>
</Window>

Look no code!

Δημοσ.

WTF? (έχω και γω τον Richter αλλά δεν το θυμάμαι αυτό)

 

 

Στο κεφαλαιο 26 Thread basics εχει ενα υποκεφαλειο Stop the madness οπου τα 'χωνει' και στο outlook για τα πολλα threads που χρησιμοποιεί. 

 

 

00s called, they want their C# back...  :P

Look ma no threads!

 

Ας γραψει και αυτος λιγο κώδικα, οχι ολα ο compiler.

Θα παθει ζαχαρο με τοσο syntactic sugar.

Δημοσ.

Μιας και πιάσετε τα async / await, να ρωτήξω και γω που δεν το έχω παρακολουθήσει το θέμα:

 

Στο λινκ του Portmaster, λέει ουσιαστικά ότι εκτελείται ασύγχρονα χωρίς να δημιουργούνται νέα threads, γιατί από κάποια στιγμή και μετά αναλαμβάνει η συσκευή να εκτελέσει τη διαδικασία και σε ειδοποιεί όταν τελειώσει.

 

Εάν αντίθετα είχαμε

private async void Button_Click(object sender, RoutedEventArgs e)
{
  await myClass.VeeeeeryLoooongCalculationAsync(data);
}

Αν αυτή η μέθοδος απλά έκανε έναν υπολογισμό στη μνήμη (π.χ. ένα παααρα πολύ μεγάλο loop), αυτό θα έτρεχε σε νέο thread;

Δημοσ.

ΝΑΙ

 

Μιας και πιάσετε τα async / await, να ρωτήξω και γω που δεν το έχω παρακολουθήσει το θέμα:

 

Στο λινκ του Portmaster, λέει ουσιαστικά ότι εκτελείται ασύγχρονα χωρίς να δημιουργούνται νέα threads, γιατί από κάποια στιγμή και μετά αναλαμβάνει η συσκευή να εκτελέσει τη διαδικασία και σε ειδοποιεί όταν τελειώσει.

 

Εάν αντίθετα είχαμε

private async void Button_Click(object sender, RoutedEventArgs e)
{
  await myClass.VeeeeeryLoooongCalculationAsync(data);
}

Αν αυτή η μέθοδος απλά έκανε έναν υπολογισμό στη μνήμη (π.χ. ένα παααρα πολύ μεγάλο loop), αυτό θα έτρεχε σε νέο thread;

ΝΑΙ.

Δεν υπαρχει thread όταν εκτελει καποιο async I/O-bound operation σε καποια συσκευη. Αναλαμβανει ο driver της (disk ,serial port, modem..).

Δημοσ.

Μιας και πιάσετε τα async / await, να ρωτήξω και γω που δεν το έχω παρακολουθήσει το θέμα:

 

Στο λινκ του Portmaster, λέει ουσιαστικά ότι εκτελείται ασύγχρονα χωρίς να δημιουργούνται νέα threads, γιατί από κάποια στιγμή και μετά αναλαμβάνει η συσκευή να εκτελέσει τη διαδικασία και σε ειδοποιεί όταν τελειώσει.

Ναι αλλά δεν είναι μόνο αυτό το ζουμί. Σίγουρα είναι μέρος της εξίσωσης με την έννοια ότι η τελική δουλειά που θέλουμε να κάνουμε (να διαβαστεί ο δίσκος) δε θα γίνει από τη CPU άρα δε χρειάζεται κάποιο thread "να την κάνει". Όπως δηλαδή και σ' αυτό το παράδειγμα όπου δε χρειάζεται να "περιμένει" κανείς ένα δευτερόλεπτο.

 

Αλλά το πιο σημαντικό (που δε φαίνεται σε κείνο το παράδειγμα) είναι πως ο κώδικας που είναι μετά το await πάει και κολλάει πάνω στο Task που κάνουμε await, κι ετσι όταν το Task τελειώσει θα συνεχίσει να εκτελεί το υπόλοιπο του κώδικά μας. Αλλά στο ενδιάμεσο κανένα (τουλάχιστον εξωτερικό του Task) thread δε θα "περιμένει" να γίνει κάτι. Αυτός είναι και ο λόγος που μπορείς να κάνεις await στον event handler για το κλικ χωρίς να μπλοκάρει το UI thread.

 

Εάν αντίθετα είχαμε

private async void Button_Click(object sender, RoutedEventArgs e)
{
  await myClass.VeeeeeryLoooongCalculationAsync(data);
}

Αν αυτή η μέθοδος απλά έκανε έναν υπολογισμό στη μνήμη (π.χ. ένα παααρα πολύ μεγάλο loop), αυτό θα έτρεχε σε νέο thread;

 

Θεωρητικά εξαρτάται από το τι κάνει το task που επιστρέφει η method που κάλεσες, αλλά πρακτικά ναι.

Δημοσ.

Και πως αποφασίζει το σύστημα για ποια task θα ξεκινήσει thread και ποια θα γίνουν με άλλο τρόπο; Στατικά την ώρα του compile, ανάλογα τι κάνει το κάθε τι;

Δημοσ.

Γενικά τα tasks (ο,τι δηλαδή είναι σχετικό με την TPL) ξεκινάνε να τρέχουν σε threads του thread pool (όπως και μέσω του thread pool γίνεται η συνεννόηση "τελείωσα εγώ να περάσει ο επόμενος" που βλέπουμε στα παραδείγματα). Απο κει και πέρα τώρα εσύ μπορείς ξεκινώντας μέσα από το thread pool να κάνεις ο,τι νομίζεις, for good or for worse.

Δημοσ.
<Window x:Class="wpfAnimations.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Label Name="lblTest" Margin="10,10,10,10">
            <Label.Triggers>
                <EventTrigger RoutedEvent="MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <StringAnimationUsingKeyFrames
                                Storyboard.TargetName="lblTest"
                                Storyboard.TargetProperty="Content"
                                Duration="0:0:1">
                                <StringKeyFrameCollection>
                                    <DiscreteStringKeyFrame Value="This"></DiscreteStringKeyFrame>
                                    <DiscreteStringKeyFrame Value="This is" />
                                    <DiscreteStringKeyFrame Value="This is a" />
                                    <DiscreteStringKeyFrame Value="This is a test" />
                                    <DiscreteStringKeyFrame Value="This is a test string" />
                                </StringKeyFrameCollection>
                            </StringAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="MouseLeave">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation
                                Storyboard.TargetName="lblTest"
                                Storyboard.TargetProperty="Opacity"
                                From="1.0"
                                To="0.0"
                                Duration="0:0:1"
                                FillBehavior="Stop"></DoubleAnimation>
                            <StringAnimationUsingKeyFrames
                                Storyboard.TargetName="lblTest"
                                Storyboard.TargetProperty="Content"
                                Duration="0:0:0"
                                BeginTime="0:0:1">
                                <StringKeyFrameCollection>
                                    <DiscreteStringKeyFrame Value=""/>
                                </StringKeyFrameCollection>
                            </StringAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Label.Triggers>
        </Label>

    </Grid>
</Window>

Look no code!

 

 

Ολο αυτο το εγραψες εσυ;

Δημοσ.

Και πως αποφασίζει το σύστημα για ποια task θα ξεκινήσει thread και ποια θα γίνουν με άλλο τρόπο; Στατικά την ώρα του compile, ανάλογα τι κάνει το κάθε τι;

Εξαρτάται πως είναι implemented το async function. Όταν δημιουργείς εσύ task με κάποιο από τα factory methods όπως Task.Run / Task.Factory.StartNew τότε το operation σου καταναλώνει thread από το threadpool. Γι' αυτό ακριβώς το λόγο δεν είναι recommended να κάνεις expose σε libs σύγχρονα operations σαν async παρά μόνο εάν είναι CPU bound. Αν αφορά Ι/Ο (network etc) τότε απλά το function σου θα είναι απαραίτητα async εφόσον θα χρησιμοποιήσεις τα built in async functions. Η άλλη περίπτωση είναι να κάνεις wrap EAP σε TAP ή χρησιμοποιώντας TaskCompletionSource να κάνεις expose σε task event based λογική όπου πάλι δεν καταναλώνεις thread.

 

Τα threads είναι resources! Eiδικά σε asp.net όπου το runtime έχει συγκεκριμένο αριθμό από threads να εξυπηρετήσει όλα τα requests το να μπλοκάρεις σε thread είναι καταστροφικό για το throughput. Μάντεψε τι κάνει ένα thread όσο περιμένεις τα αποτελέσματα μιας sp, ενώ θα μπορούσε να εξυπηρετήσει άλλο request απλά blockaρει. Το ADO καθώς και το EF πχ από την έκδοση 6 και μετά κάνουν expose async methods.

 

 

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...