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

 

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

COM objects and Threads....

Îåêßíçóå áðü ôï ìÝëïò odyodyodys. Τελευταία δημοσίευση από το μέλος BruteForce στις 06-12-2007, 17:14. Υπάρχουν 4 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  02-11-2007, 14:58 36908

    COM objects and Threads....

    Γεια σας,

    Είμαι νέο μέλος του dotNETZone και ελπίζω αυτό το άρθρο να το έβαλα στο σωστό μέρος...

    Έχω μία εφαρμογή που χρησιμοποιεί το DirectShow για να παίζει video (Video Player).
    Η εφαρμογή τρέχει 3 φορές ταυτόχρονα (διαφορετικά video σε 3 οθόνες) και την διαχείριση τους την έχει ένα άλλο πρόγραμμα που απλώς τα ξεκινάει.
    Το πρόβλημά μου είναι ότι η εφαρμογή χρησιμοποιεί 3 threads και τα 2 από αυτά χρειάζονται τα COM αντικείμενα....

    Το κύριο Thread του process (t1) και ένα thread που δημιουργεί αυτό (t2).
    Δεν μπορώ να καταλάβω που και πως πρέπει να εγκαθιστώ την COM.

    Δοκίμασα..
    CoInitialize(NULL); στο t1.
    Αλλά δεν μπορεί να δημιουργήσει αντικείμενα το t2.

    CoInitializeEx(NULL,COINIT_MULTITHREADED); στο t1.
    Μπορεί να δημιουργήσει COM αντικείμενα και το άλλο thread αλλά αποτυγχάνει να ξεκινήσει 2η φορά η εφαρμογή...

    Χρειάζομαι επειγόντος βοήθεια...!!


    Δημοσίευση στην κατηγορία: ,
  •  02-11-2007, 15:47 36911 σε απάντηση της 36908

    Απ: COM objects and Threads....

    Μετέφερα εδώ την ερώτηση σου γιατί το COM+ δεν έχει σχέση με το DirectShow. Το COM+ είναι τεχνολογία καθαρά για transaction management και distributed εφαρμογές. Τώρα, θα μου πεις γιατί το ονομάσανε COM+? Άλλη μία ατυχής ονομασία από το marketing της Microsoft.

    Όσον αφορά την ερώτηση σου ... ομολογώ ότι δεν πολυκατάλαβα τί ρωτάς. Όταν λες "εγκαθιστώ" εννοείς Initialize? Οπότε η ερώτηση σου είναι "Πως κάνω initialize το COM σε διαφορετικά threads?". Απ' όσο θυμάμαι, το COM πρέπει να το κάνεις Initialize σε κάθε thread που θα το χρησιμοποιήσει, όχι μόνο στο κυρίως thread. Από εκεί και πέρα ... δεν έχω ασχοληθεί παραπάνω με COM και multithreading. Είναι εξαιρετικά δύσκολο μανίκι να το κάνεις μόνος σου και θέλει διάβασμα. Το ATL Library της Visual C++ μπορεί να βοηθήσει πάντως.

    Γιατί δεν χρησιμοποιείς τις αντίστοιχες κλάσεις του .NET για DirectX? Το multithreading είναι πολύ ευκολότερο εκεί, άσε που για COM δεν πρόκειται πλέον να βρεις και πολλά βιβλία ή άρθρα.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  02-11-2007, 21:51 36924 σε απάντηση της 36908

    Απ: COM objects and Threads....

    Όπως πολύ σωστά σου είπε κι ο Παναγιώτης, πρέπει να καλέσεις την CoInitializeEx σε κάθε thread που ανοίγεις, η οποία στο τέλος του πρέπει να συνοδεύεται και από το αντίστοιχο CoUninitialize. Αν την καλέσεις όπως στο post σου, με COINIT_MULTITHREADED, τότε τα αντικείμενα που θα φτιάξεις θα ζουν στο multithreaded apartment του COM, πράγμα που σημαίνει ότι μπορούν να "δέχονται" κλήσεις από πολλά threads ταυτόχρονα.


    Νατάσα Μανουσοπούλου
  •  03-11-2007, 05:26 36929 σε απάντηση της 36924

    Απ: COM objects and Threads....

    Ναι συγνώμη, Initialize εννοούσα..

    Το θέμα μου είναι ότι είτε καλέσω CoInitializeEx με σημαία για multithreading μόνο στο κυρίως thread είτε CoInitializeEx με σημαία για το thread και το καλέσω στο κάθε thread ξεχωριστά, έχω προβλήματα...
    (Εννοείται ότι πριν το κλείσιμο κάθε thread έχω CoUninitialize() )

    Όσο για βιβλία της Com, έχω ένα, αλλά δεν αναφέρει τίποτα παραπάνω από αυτα..

    Ευχαριστώ πάντως... Stick out tongue
  •  06-12-2007, 17:14 38067 σε απάντηση της 36929

    Απ: COM objects and Threads....

    Κατ'αρχάς δεν είδα καμιά αναφορά στο COM+ στο αρχικό post, οπότε αναρωτιέμαι πώς προέκυψε.
    Το COM+ είναι επέκταση του COM/DCOM συν δυνατότητες για resource management (διάβαζε transactions).
    Απολύτως λογικό να λέγεται COM+ κατά τη γνώμη μου.

    Γενικά να παίζεις με COM objects και threads είναι living on the fast lane. Αν βάλεις τώρα και το DirectShow στην υπόθεση τότε είσαι έτοιμος να σου πάρουν μέτρα.

    Η CoInitialize(Ex) αυτό που κάνει είναι να δηλώνει στο COM+ runtime το threading model του thread και ΜΟΝΟ.
    Δηλαδή σε ποιό "COM apartment" θα ζει το thread και ΜΟΝΟ.
    Το σε ΠΟΙΟ apartment θα ζήσουν τα COM objects που δημιουργεί το thread, εξαρτάται από το threading model των COM objects, και εν μέρει του creator.

    Υπάρχει ΕΝΑ multithreaded apartment (MTA) και όσα θες single threaded apartments (STA).

    Από εκεί και πέρα, όταν ένα DLL COM object είναι SingleThreaded τότε πάει πάντα σε ένα STA. Αν ο creator του είναι STA thread, τότε πάει στο apartment του creator. Αν ο creator είναι στο MTA, τότε φτιάχνεται ένα STA apartment για να ζήσει το COM object.
    Ένα DLL COM Object που έχει threading model BOTH πάει εκεί που είναι ο creator του.

    Τώρα τα πράγματα σκουραίνουν όταν καλείς COM objects τα οποία θα σε καλέσουν πίσω ή κάνουν hook τα COM events σου και σε καλούν και τα καλείς κλπ κλπ. Είναι πολύ εύκολο να προκύψει deadlock σε αυτές τις περιπτώσεις. Το βασικό πάντως είναι ότι για να κάνει δεχτεί ένα COM object σε STA apartment μία κλήση (method call) πρέπει το thread του STA να είναι διαθέσιμο να κάνει pump ένα κρυμμένο message loop μέσα στο COM. Αν αυτό το thread είναι blocked περιμένοντας κάτι, τότε τα ρολλά είναι κατεβασμένα. Εκεί χρησιμεύει η μαγική MsgWaitForMultipleObjects για να φτιάξεις δικό σου message pump. Όταν τη χρειαστείς θα καταλάβεις τι κάνει.

    Ένα πανεύκολο deadlock είναι αν πας να κάνεις διάφορα non-trivial πράγματα μέσα από μια DirectShow callback.
    Anyway, αν έχεις ακόμα πρόβλημα, let me know.

    The fact that the program works is irrelevant.
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems