Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Περισσότερες από μία φόρμες με κοινή εμφάνιση

Îåêßíçóå áðü ôï ìÝëïò xrousaios. Τελευταία δημοσίευση από το μέλος Παναγιώτης Καναβός στις 15-06-2016, 12:20. Υπάρχουν 2 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  09-06-2016, 13:37 77736

    Περισσότερες από μία φόρμες με κοινή εμφάνιση

    Καλημέρα,

    Θα ήθελα να εκθέσω το ακόλουθο πρόβλημα σχεδιασμού που έχω, στο Visual Studio με Visual Basic.
    Η εφαρμογή μου αποτελείται από μερικές φόρμες και μία βάση δεδομένων (Microsoft Access).

    Μία από τις φόρμες, συνδέεται με το Microsoft Outlook. Μέσα σε αυτήν την φόρμα, διαχειρίζομαι δύο events :
    - Το event της  άφιξης ενός e-mail στο Outlook. Γιά κάθε e-mail που έρχεται, εκκινεί μία διαδικασία επεξεργασίας του, μέσω της οποίας καταχωρώ κάποια στοιχεία του στην βάση δεδομένων και, εμφανίζω το θέμα του στην οθόνη του χρήστη.    
    - To event ενός timer, ο οποίος εκκινεί κάθε χχ λεπτά. Κάθε φορά που ξεκινάει ο timer, διαβάζω τα αφιχθέντα e-mails μέχρι εκείνη την στιγμή,  πραγματοποιώ κάποια επεξεργασία και εμφανίζω κάποιες πληροφορίες στην ίδια οθόνη.

    Το πρόβλημα είναι ότι, αρκετά συχνά, συμβαίνει να επικαλύπτεται η λειτουργία των δύο events και το πρόγραμμα, μετά από αυτό, χάνει την επαφή του με το outlook.

    Από την περιγραφή, φαίνεται ότι και τα δύο events, λειτουργούν κάτω από το ίδιο main-message loop.
    Σκέφτομαι ότι, ένας ριζικός τρόπος λύσης του προβλήματος είναι να διαχωρίσω τις δύο διεργασίες σε δύο διαφορετικές φόρμες και κάθε μία να τρέχει σε διαφορετικό main-message loop (Π.χ. και οι δύο φόρμες να εκκινούν μέσω μίας άλλης κύριας φόρμας, σε διαφορετικό thread η κάθε μία) .

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

    ΑΝ πάλι χρησιμοποιήσω MDI, καταλήγω και πάλι να λειτουργούν και οι δύο φόρμες κάτω από το ίδιο main-message loop της MDI, οπότε, η μία φόρμα περιμένει να τελειώσει η εργασία της άλλης φόρμας και το ανάποδο. Όπερ άτοπον.   

     Κάπου εδώ, μάλλον έχω χάσει την μπάλα....

    Κάθε ιδέα επί του θέματος, θα μου είναι ιδιαίτερα χρήσιμη

     

    Ευχαριστώ εν των προτέρων γιά κάθε βοήθεια.

    Γιώργος 

  •  15-06-2016, 12:08 77738 σε απάντηση της 77736

    Απ: Περισσότερες από μία φόρμες με κοινή εμφάνιση

    Τελικά το έλυσα χρησιμοποιώντας ένα Thread pool στο οποίο στέλνω μία structure με πληροφορίες γιά κάθε εισερχόμενο e-mail. Η Thread pool εκκινεί μία διαδικασία η οποία κάνει όλα τα υπόλοιπα.

    Πρός ώρας, δείχνει να λειτουργεί σωστά...

     

  •  15-06-2016, 12:20 77739 σε απάντηση της 77738

    Απ: Περισσότερες από μία φόρμες με κοινή εμφάνιση

    Αν είχες ρωτήσει κατευθείαν "Θέλω να επεξεργαστώ πολλά εισερχόμενα e-mail" θα σου έλεγα απευθείας να χρησιμοποιήσεις ένα ActionBlock από το TPL Dataflow library. Δεν υπάρχουν πολλαπλά message loops σε μία Windows εφαρμογή, ούτε χρειάζονται για να επεξεργαστείς κάτι ασύγχρονα. Ακριβώς επειδή υπάρχει μόνο ένα Message loop, δεν μπορείς να πειράξεις και ένα UI control από διαφορετικά threads.

     Αντί γι αυτό, καλύτερα να χρησιμοποιήσεις ένα ActionBlock<T> το οποίο θα καλεί ένα function για να επεξεργαστεί κάθε μήνυμα. To ActionBlock κάνει buffer τα εισερχόμενα μηνύματα αν και μπορείς να ορίσεις όριο, για να μην μεγαλώσει υπερβολικά ο buffer αν είναι αργό το function. Επίσης μπορείς να ορίσεις ότι θα χρησιμοποιηθούν παραπάνω από ένα tasks για την επεξεργασία των μηνυμάτων, οπότε η επεξεργασία θα γίνει παράλληλα.

    Ο κώδικας είναι πολύ απλός:

     

        var myBlock = new ActionBlock<MyEmail>(it => MyProcessingMethod(it) );

        foreach (var email in myListOfEmails)

        {

            myBlock.Post(email); 

        } 

     

    Όταν τελειώσει η επεξεργασία και θέλεις να κλείσεις το block, καλείς την Complete() και περιμένεις να τελειώσει το Completion task, το οποίο σημαίνει ότι καθάρισαν οι εκκρεμότητες:

     

        myBlock.Complete();

       await myBlock.Completion; 

    Το TPL Dataflow περιέχει και άλλα χρήσιμα blocks. Για παράδειγμα, το TransformBlock καλεί ένα function το οποίο λαμβάνει ένα input και επιστρέφει ένα διαφορετικό output. Αυτό σου επιτρέπει να σπάσεις τη διαδικασία της επεξεργασίας σε βήματα, όπως θα έκανες και στο command line και να περάσεις τα αποτελέσματα του ενός βήματος, στο επόμενο. Κάθε βήμα εκτελείται με διαφορετικά tasks, οπότε έχεις άλλο ένα τρόπο να πετύχεις ασύγχρονη επεξεργασία. Πχ.

     

        var myParser=new TransformBlock<MyEmail,MyCustomer>(x=>GetCustomerFromEmail(x));

        var myBlock = new ActionBlock<MyCustomer>(x=> DoSomethingWithCustomer(x));

        myParser.LinkTo(myBlock, new DataflowLinkOptions { PropagateCompletion = true });

     

       ....

       myParser.Post( email);

       ... 

       myParser.Complete();

       await myBlock.Completion;

     

    Εδώ το LinkTo μεταφέρει το αποτέλεσμα από το πρώτο βήμα στο επόμενο. Το PropagateCompletion σημαίνει ότι αν ολοκληρωθεί το προηγούμενο βήμα, θα πρέπει να ολοκληρωθεί και το επόμενο. Μόλις τελειώσουν τα μηνύματα καλείται η Complete() στο πρώτο βήμα και περιμένουμε μέχρι να τελειώσει και το τελευταίο μήνυμα 


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems