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

 

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

Cross threading και ανάλυση emf αρχείου.

Îåêßíçóå áðü ôï ìÝëïò sgkin. Τελευταία δημοσίευση από το μέλος Παναγιώτης Καναβός στις 03-03-2012, 17:11. Υπάρχουν 5 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  02-03-2012, 00:15 69509

    Cross threading και ανάλυση emf αρχείου.

    Αυτό που θέλω να κάνω είναι να αναλύσω ένα .emf αρχείο.
    Βρήκα ένα παράδειγμα κώδικα σε VB.NET εδώ .   http://www.vb-helper.com/howto_net_enumerate_metafile.html (Enumerate the records in a Windows metafile (WMF) or enhanced metafile (EMF) in VB .NET).

    Μετέτρεψα τον κώδικα σε c# και τώρα η μέθοδος που κάνει την ανάλυση έχει αυτή τη μορφή

    public  bool ListRecords(EmfPlusRecordType recordType, int flags, int dataSize, IntPtr data, PlayRecordCallback callbackData)

            {
                listBox.Items.Add(recordType.ToString());
              
                }
                return true;

            }

    την καλώ μέσα από ένα κουμπί κάπως έτσι.

    private void button1_Click(object sender, EventArgs e)

            {
                Metafile mf = new Metafile("test.emf");
                this.CreateGraphics().EnumerateMetafile(mf, new PointF(0, 0), ListRecords);
                mf.Dispose();

             }

    Η κλήση του "κιτρινισμένου" στον αυθεντικό κώδικα (VB.NET) είναι Me.CreateGraphics.EnumerateMetafile(  mf, New PointF(0, 0),   AddressOf ListRecords)

    Όσες φορές και να πατήσω το κουμπί, ο κώδικας εκτελείται κανονικά, και μου παρουσιάζει την ανάλυση του emf.

    Μεσα στον κώδικα που θέλω να το χρησιμοποιήσω, επειδή υπάρχει cross-threading πρόβλημα,  έχω τον κώδικα

      MethodInvoker invoker = () =>
                         {
                             button1.PerformClick();  //ektelei ton kodika tou koumpiou 1.

                         };
                        if (button1.InvokeRequired)
                        {
                            Invoke(invoker);
                        }
                        else
                        {
                            invoker();
                        }


    Με αυτό τον κώδικα το "  this.CreateGraphics().EnumerateMetafile(mf, new PointF(0, 0), ListRecords);" εκτείλεται είτε μια φορά είτε καμία. Για πιο λόγο; Μήπως θα έπρεπε να βάλω κάτι αντίστοιχο του AddressOf και στον κώδικα της c#; Σε 2-3 σαιτ που κοίταξα, έλεγαν ότι δεν χρειάζεται να βάλουμε κάτι.

    Ή μήπως είναι κάτι άλλο;



    Δημοσίευση στην κατηγορία: ,
  •  02-03-2012, 01:41 69510 σε απάντηση της 69509

    Απ: Cross threading και ανάλυση emf αρχείου.

    Από περιέργεια , τι θες να αναλύσεις στο EMF;
  •  02-03-2012, 09:50 69513 σε απάντηση της 69510

    Απ: Cross threading και ανάλυση emf αρχείου.

    Βαασικά θέλω να πάρω το κείμενο. Αν πετύχω π.χ την ΕmfExtTextOutW παίρνω το κείμενο.

    Αυτό το κομμάτι μου δουλεύει, απλά το πρόβλημά μου είναι αυτό που περιέγραψα προηγουμένως.
  •  02-03-2012, 10:52 69514 σε απάντηση της 69513

    Απ: Cross threading και ανάλυση emf αρχείου.

    Καλώ την test() από thread του button2 και δεν βγάζει πρόβλημα για cross-threading. 
    Εσύ πως την καλείς; Μήπως έχεις κάποιο επιπλέον thread;  

           private void button2_Click(object sender, EventArgs e)
            {
                System.Threading.Thread t = new System.Threading.Thread(test);
                t.Start();
            }
            private void test()
            {
                MethodInvoker invoker = () =>
                {
                    button1.PerformClick();  //ektelei ton kodika tou koumpiou 1.
                };
                if(button1.InvokeRequired)
                {
                    this.Invoke(invoker);
                }
                else
                {
                    invoker();
                }
            }
    Πάντως το κείμενο της EmfExtTextOutW δεν είναι απλά unicode.
  •  03-03-2012, 10:00 69534 σε απάντηση της 69514

    Απ: Cross threading και ανάλυση emf αρχείου.

    Δεν έτρεχα τον κώδικα σε διαφορετικό thread, απλά είχα τον κώδικα

    MethodInvoker invoker = () =>
                {
                    button1.PerformClick();  //ektelei ton kodika tou koumpiou 1.
                };
                if(button1.InvokeRequired)
                {
                    this.Invoke(invoker);
                }
                else
                {
                    invoker();
                }
    εκεί που ήθελα. γιατί και σε μια άλλη περίπτωση που μου έβγαζε πρόβλημα cross-threading, έβαλα ένα MethodInvoker invoker, και λύθηκε το θέμα.
    Τωρα δουλεύει, ευχαριστώ.	
  •  03-03-2012, 17:11 69536 σε απάντηση της 69534

    Απ: Cross threading και ανάλυση emf αρχείου.

    Αν δεν έχεις διαφορετικό thread τί το θέλεις το Invoke? Αν βάζεις κώδικα "μήπως", χωρίς να καταλαβαίνεις τί κάνει ή γιατί, θα αντιμετωπίσεις προβλήματα όπως αυτό που αντιμετωπίζεις τώρα.

    Ο κώδικας έχει άλλα, σοβαρότερα προβλήματα. Καταρχήν, είναι μεγάλο σφάλμα να βάζεις λογική πίσω από το Click event. Όπως βλέπεις και ο ίδιος, μετά είναι πολύ δύσκολο να την καλέσεις αν θέλεις να τη χρησιμοποιήσεις και σε άλλο σημείο. Αντί να χρησιμοποιείς το PerformClick απλά φτιάξε μία άλλη μέθοδο την οποία θα καλείς από όπου αλλού θέλεις.

    Επιπλέον ο κώδικας στον οποίο βασίστηκες είναι κακός:
    • Αντί να χρησιμοποιήσει κάποιο using για να καλέσει αυτόματα το Dispose, το αφήνει στη μοίρα του. Αν υπάρξει κάποιο exception το Dispose δεν θα κληθεί ποτέ
    • "Καρφώνει" ένα AddressOf για να κρύψει τον τύπο του callback αντί να κάνει cast σε Graphics.EnumerateMetafileProc
    Τέλος, δοκίμασες να βάλεις κάποια breakpoints για να δεις τί κάνει ο κώδικας σου? Αν δεν σηκώνει κάποιο exception, μάλλον θα πρέπει να δεις τί καλείται τελικά και τί όχι.

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