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

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

Δημοσ.

Έχω ένα θεματάκι. Ανέλαβα να refactory κώδικα που εμφανίζει δεδομένα σε δεδομένα σε ένα grid. Τα δεδομένα τα τραβάμε από μία βάση με εκατομμύρια εγγραφές, υπόκεινται σε filtering (linq) και στο τέλος έχουμε μια λίστα με τα δεδομένα που θέλουμε, τα οποία συνήθως είναι ΠΟΛΛΑ (άνετα 1500 γραμμές).

 

Ας ονομάσουμε όλη αυτή την διαδικασία, Requery! Καλά; καλά...

 

Θέλουμε λοιπόν να γίνεται Requery κάθε φορά που ο χρήστης πειράζει τα φίλτρα του και κάθε φορά βαράει ο trigger (κάποιος συνάδελφος άλλαξε κάτι). Καλά κι εδώ; Καλά..

 

Πάμε στο ζουμί..

Όπως είναι τώρα, η Requery δεν είναι ασύγχρονη, με αποτέλεσμα να έχουμε πολύ κακό performance. Ο χρήστης κάθε φορά που πειράζει τα φίλτρα πρέπει να περιμένει να έρθουν τα δεδομένα (<1s συνήθως αλλά αν γίνουν ΠΟΛΛΑ μπορεί να κάνει και 3-4s).

 

Αυτό που θέλω να πετύχω, είναι η Requery να λειτουργεί σαν singleton async ajax request. Η μία κλήση της να ακυρώνει την προηγούμενη δηλαδή (ακόμα κι αν αυτή δεν έχει ολοκληρωθεί ακόμα) και έτσι στο τέλος να παίρνουμε τα αποτέλσματα του τελευταίου φιλτραρίσματος. Ελπίζω να γίνομαι κατανοητός.

 

Σε τεχνικό επίπεδο, κατάφερα να απομονώσω την Requery σε δικό της thread. Κατάφερα να το abort ελεγχόμενα αλλά όταν έρχεται η ώρα να στείλω τα δεδομένα μου στο πινακάκι, πετάει exception ότι το thread was being aborted.. Δοκίμασα να παίξω με Dispatcher.Invoke αλλά πάλι τα ίδια..

 

Υπάρχει κάποιος που να έχει πετύχει αυτή την λειτουργικότητα;; Κανα hint? Κανα clue? Κανα inside?

Δημοσ.

Το Thread.Abort δεν είναι ποτέ η σωστή λύση, κάντο σωστά και problem solved.

 

Κατά τα άλλα χωρίς λίγο κώδικα τι περιμένεις ακριβώς; "Όταν έρχεται η ώρα να στείλω τα δεδομένα πετάει exception" => δεν έχουμε ιδέα τι πας να κάνεις.

  • Like 1
Δημοσ.

Το Thread.Abort δεν είναι ποτέ η σωστή λύση, κάντο σωστά και problem solved.

 

Κατά τα άλλα χωρίς λίγο κώδικα τι περιμένεις ακριβώς; "Όταν έρχεται η ώρα να στείλω τα δεδομένα πετάει exception" => δεν έχουμε ιδέα τι πας να κάνεις.

 

Ποια είναι η σωστή λύση;

 

Δυστυχώς δεν μπορώ να δημοσιεύσω κώδικα :/

 

Εννοώ ότι όταν έχω λάβει και επεξεργαστεί τα δεδομένα και έρχεται ή ώρα να τα περάσω στον πίνακα, πετάει αυτό το Thread Being Aborted exception

Δημοσ.

Η σωστή λύση είναι να έχεις ένα δικό σου μηχανισμό (και όχι OS-level) για να σταματήσεις τον υπολογισμό που κάνεις όταν χρειαστεί. Πιθανότατα αυτό σημαίνει ότι πρέπει να μετατρέψεις σε async το οτιδήποτε κάνεις, στην οποία περίπτωση ακυρώνεις με cancellation token.

Δημοσ.

Πες μας τουλάχιστον που γίνεται το filtering. Στην μνήμη; Στην βάση; Μπορείς να cache-άρεις με vary by filter; δώσε κάτι.

Επίσης, γύρνα το async αν στο επιτρέπει το stack σου, όπως και να 'χει.

Δημοσ.

Ποια είναι η σωστή λύση;

 

Δυστυχώς δεν μπορώ να δημοσιεύσω κώδικα :/

 

Εννοώ ότι όταν έχω λάβει και επεξεργαστεί τα δεδομένα και έρχεται ή ώρα να τα περάσω στον πίνακα, πετάει αυτό το Thread Being Aborted exception

 

Κατ αρχήν κοίτα να χρησιμοποιήσεις background worker, είναι παρεξηγημένος αλλά κάνει θαύματα όταν θες να έχεις έλεγχο του το progress ενός thread, και να μπορείς να το τερματήσεις πρόωρα χωρίς πολλά προβλήματα, αν επέλεθει κάποιο event.

 

Επίσης αν έχεις συνδέσει σωστά τα δεδομένα μέσω MVVM στο WPF και το ΕF και δεν χρησιμοποιείς κανένα περίεργο query με join στην Linq δεν θα έχεις κανένα πρόβλημα στο performance. Αν έχεις, ή κάνεις πολλαπλές ενώσεις πινάκων στο τελικό αποτέλεσμα, rule of thumb φτιάξε ένα view (και τα αντίστοιχα μοντέλα) στην βάση δεδομένων και κάνε απλό select και where στην Linq. 

Δημοσ.

Η σωστή λύση είναι να έχεις ένα δικό σου μηχανισμό (και όχι OS-level) για να σταματήσεις τον υπολογισμό που κάνεις όταν χρειαστεί.

Δεν νομιζω να ειναι καποιο loop ωστε να κανει break όταν κάποια μεταβλητή γίνει true η μέσω AutoResetEvent.

Ειναι ένα call προς μια βαση και δεν εχει ελεγχο στο ποσο θα καθυστερήσει να φέρει τα αποτελεσματα.

Δημοσ.

Δεν νομιζω να ειναι καποιο loop ωστε να κανει break όταν κάποια μεταβλητή γίνει true η μέσω AutoResetEvent.

Ειναι ένα call προς μια βαση και δεν εχει ελεγχο στο ποσο θα καθυστερήσει να φέρει τα αποτελεσματα.

 

Σαφώς και μπορείς να έχεις έλεγχο, δες SqlCommand.Cancel και όλες τις -Async μεθόδους. Ανάλογα με το τι DAL χρησιμοποιεί μπορεί να είναι λιγότερο ή περισσότερο εύκολο, αλλά σίγουρα γίνεται.

Δημοσ.

Έχω ένα θεματάκι. Ανέλαβα να refactory κώδικα που εμφανίζει δεδομένα σε δεδομένα σε ένα grid. Τα δεδομένα τα τραβάμε από μία βάση με εκατομμύρια εγγραφές, υπόκεινται σε filtering (linq) και στο τέλος έχουμε μια λίστα με τα δεδομένα που θέλουμε, τα οποία συνήθως είναι ΠΟΛΛΑ (άνετα 1500 γραμμές).

 

Ας ονομάσουμε όλη αυτή την διαδικασία, Requery! Καλά; καλά...

 

Θέλουμε λοιπόν να γίνεται Requery κάθε φορά που ο χρήστης πειράζει τα φίλτρα του και κάθε φορά βαράει ο trigger (κάποιος συνάδελφος άλλαξε κάτι). Καλά κι εδώ; Καλά..

 

Πάμε στο ζουμί..

Όπως είναι τώρα, η Requery δεν είναι ασύγχρονη, με αποτέλεσμα να έχουμε πολύ κακό performance. Ο χρήστης κάθε φορά που πειράζει τα φίλτρα πρέπει να περιμένει να έρθουν τα δεδομένα (<1s συνήθως αλλά αν γίνουν ΠΟΛΛΑ μπορεί να κάνει και 3-4s).

 

Αυτό που θέλω να πετύχω, είναι η Requery να λειτουργεί σαν singleton async ajax request. Η μία κλήση της να ακυρώνει την προηγούμενη δηλαδή (ακόμα κι αν αυτή δεν έχει ολοκληρωθεί ακόμα) και έτσι στο τέλος να παίρνουμε τα αποτέλσματα του τελευταίου φιλτραρίσματος. Ελπίζω να γίνομαι κατανοητός.

 

Σε τεχνικό επίπεδο, κατάφερα να απομονώσω την Requery σε δικό της thread. Κατάφερα να το abort ελεγχόμενα αλλά όταν έρχεται η ώρα να στείλω τα δεδομένα μου στο πινακάκι, πετάει exception ότι το thread was being aborted.. Δοκίμασα να παίξω με Dispatcher.Invoke αλλά πάλι τα ίδια..

 

Υπάρχει κάποιος που να έχει πετύχει αυτή την λειτουργικότητα;; Κανα hint? Κανα clue? Κανα inside?

   Αμα μιλαμε για 1500 row, αν υποθεσουμε οτι δεν εχεις κανενα περιεργο column με κατεβατη εκθεση, δεν θα πρεπει να εχεις προβλημα στην αποδοση. Απλα κανε το request async, ισως και με background thread, οπως ανεφερε ο φιλος παραπανω που ειναι εξαιρετικο αμα μιλαμε για single async requests χωρις να περιπλεκονται.

  Αυτο που θα τσεκαρα και θα πειραματιζομουνα, μαντευοντας φυσικα επειδη δεν ξερουμε ουτε κωδικα ουτε βαση δεδομενων ουτε τιποτα ειναι το request στην database.    

Δημοσ.

Λίγο feedback από σήμερα..

 

έπαιξα με CancelationToken όπως είπε ο Defacer, μάλλον είμαι σε καλό δρόμο αλλά δεν έχω ακόμα το επιθυμητό αποτέλεσμα.

 

Έκανα async την Requery και δουλεύω στην ουσία με ένα Thread το οποίο (μέσω του token) ακυρώνω και τρέχω εκ νέου κάθε φορά που η Requery καλείται.

 

Το αποτέλεσμα είναι ότι όσο περισσότερο καλείται η Requery (όσο συχνότερα πειράζουμε τα φίλτρα), τόσο πιο πολύ "βαραίνει" μέχρι να κολλήσει το πρόγραμμα.. Αυτό με κάνει να πιστεύω ότι το Thread @ρχίδια ακυρώνεται..

 

Το επιθυμητό αποτέλεσμα είναι ο χρήστης να μπορεί να πειράζει τα φίλτρα απρόσκοπτα όποτε θέλει (και κατά συνέπεια να καλεί την Requery απανωτά) και μόλις τα αφήσει ήσυχα να λάβει τα δεδομένα που αρμόζουν στο τελευταίο φιλτράρισμα.

 

Αύριο θα ανεβάσω παραποιημένο τον κώδικα για να μιλήσουμε λίγο πιο σταράτα

Δημοσ.

Πρέπει να ακυρώσεις και το query στη βάση όπως είπε ο def πιο πάνω. Επίσεις βάλε ένα lock στο connection εκεί μέσα στην async method

Δημοσ.

   Αυτο που δεν καταλαβα, ειναι εφοσον τα περισσοτερα queries οπως ειπες παιρνουνε 1 seconds, τι λογικη εχει να τα ακυρωσεις; Εστω και 3,4 δευτερα το μεγιστο που ανεφερες, δεν ειναι λογικο να υπαρχουν πολλαπλα requests σε αυτο το διαστημα. Μεχρι να στειλεις το cancelation token, το request θα εχει τελειωσει.

 

   Και μια αλλη παρατηρηση δεν βλεπω λογο να προβαλεις 1500 σειρες ταυτοχρονα σε ενα datagrid. Σπαστα σε περισσοτερες απο μια σελιδες, η καθε μια να δειχνει χ αριθμο σειρων τον οποιο ο χρηστης καθοριζει. Για ακομη καλυτερη αποδoση οταν φορτωνεις μια, με background threads να ετοιμαζεις την επομενη και την προηγουμενη, αλλα αμα προβαλεις μερικες εκατονταδες σε καθε σελιδα, δεν ειναι απαραιτητο. Και με ενα απλο search box κανεις ενα γρηγορο search σε ολο το table. 

Δημοσ.

Τα ακυεωνεις για να μην έχεις bottleneck. Το αν ακυρωθεί είναι αδιάφορο, το ζητούμενο είναι να μην έχεις δύο και queries.

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

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

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

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

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

Σύνδεση

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

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