Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2005
    Messaggi
    247

    [DELPHI] Could not obtain OLE control window handle

    Salve a tutti,

    dal momento che la mia applicazione lavora in multithreading con TADOTable e TADOQuery, sono costretto a lanciare CoInitializeEx(nil, COINIT_MULTITHREADED) quale prima istruzione del mio programma.

    Sto realizzando un'applicazione Delphi con interfaccia MDI.
    Su un form è presente una TADOQuery. Putroppo, nel momento in cui la form incriminata viene creata come MDIChildren, viene lanciata l'eccezione "Could not obtain OLE control window handle". Ciò non accade se la form viene creata automaticamente all'inizio e mostrata come modal form.

    Che cosa posso fare? Devo forse togliere CoInitializeEx(nil, COINIT_MULTITHREADED) e mettere un CoInitialize(nil) e CoUninitialize rispettivamente all'inizio e alla fine del metodo Execute di ciascuno dei miei thread?

    Grazie in anticipo

  2. #2

    Re: [DELPHI] Could not obtain OLE control window handle

    Originariamente inviato da firefox88
    Salve a tutti,

    dal momento che la mia applicazione lavora in multithreading con TADOTable e TADOQuery, sono costretto a lanciare CoInitializeEx(nil, COINIT_MULTITHREADED) quale prima istruzione del mio programma.

    Sto realizzando un'applicazione Delphi con interfaccia MDI.
    Su un form è presente una TADOQuery. Putroppo, nel momento in cui la form incriminata viene creata come MDIChildren, viene lanciata l'eccezione "Could not obtain OLE control window handle". Ciò non accade se la form viene creata automaticamente all'inizio e mostrata come modal form.

    Che cosa posso fare? Devo forse togliere CoInitializeEx(nil, COINIT_MULTITHREADED) e mettere un CoInitialize(nil) e CoUninitialize rispettivamente all'inizio e alla fine del metodo Execute di ciascuno dei miei thread?

    Grazie in anticipo
    mmm...

    io credo che dovresti mettere nel MAIN(o form padre) sia IL TAdoConnection che i vari TAdoQuery e TAdoTAble che poi utilizzi con le varie finestre figlie(che ovviamente avranno un USES MAIN in incipit)...

    esempio

    nel main
    codice:
      class main : class(Tform)
     {
        ...
       db:TADOConnection;
       qry:TADOQuery;
       tb: TADOTable;
      }
      ...
      procedure main.FormShow(Sender: TObject);
      begin
        //imposti i valori di connessione
       db.ConnectionString:='....';
      //connetti il database
       db.connected:=true;
      //imposti i qry e i table
       qry.connection:=db;
       tb.connection:=db;
      end;
    nella form figlia
    codice:
      ...
      implementation
      uses main;
      ...
      procedure figlia.usaqry;
      begin
        main.qry.close;
        main.qry.sql.clear;
        main.qry.sql.text:='SELECT ....' ;
        ...
      end;

    spero di esser stato chiaro...
    ciao
    "Due cose riempiono l’animo di ammirazione e venerazione sempre nuova e crescente, quanto piú spesso e piú a lungo la riflessione si occupa di esse: il cielo stellato sopra di me, e la legge morale in me..." Immanuel Kant

  3. #3
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,463
    Non ho ben compreso il problema, ma forse si sta utilizzando una stessa ADOConnection da più thread differenti?
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  4. #4
    Utente di HTML.it
    Registrato dal
    Sep 2005
    Messaggi
    247
    Mi scuso per la risposta tardiva, comunque sì, sto usando la stessa TADOConnection (e altri componenti TADOQuery, TADOTable, ecc...) da più thread differenti. Per ora ho risolto mettendo un CoInitialize(nil) all'inizio del metodo Execute di ogni thread che si avvale di oggetti ADO.

    Esiste un metodo più "pulito"?

  5. #5
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,463
    Originariamente inviato da firefox88
    Esiste un metodo più "pulito"?
    Sì: non si possono usare componenti da più thread, a meno di non prendere provvedimenti specifici, in quanto le classi della VCL (salvo quelle appositamente progettate) non sono multithreading. Questo consente di massimizzare le performance dell'intera libreria, ma è necessario proteggere l'accesso ai componenti quando questo avviene da più thread.

    E' possibile risolvere il problema in due modi (sono i primi che mi vengono in mente).

    Quello più semplice è, secondo me, la creazione di un componente ADOConnection (e correlati) per ciascun thread che deve accedere ai dati, affinché non vi sia il tentativo di accesso contemporaneo ad un unico componente.

    In alternativa, è possibile "sincronizzare" l'accesso ai componenti delegandolo al thread primario dell'applicazione, attraverso l'uso del metodo Synchronize che viene fornito dalla classe TThread.

    So che è una spiegazione a grandi linee... prova a ricercare un po' di documentazione a riguardo per chiarire gli aspetti inerenti all'uso delle classi e dei metodi citati ed eventualmente scrivi ancora se hai altri dubbi.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2005
    Messaggi
    247
    Non ti preoccupare, la tua spiegazione è stata molto esauriente, e ho capito perfettamente qual è il problema.

    Nel mio caso, il rischio che due thread vengano eseguiti in simultanea e perciò lavorino insieme con la stessa TADOConnection non esiste: ho fatto in modo che, benché la TADOConnection sia una sola e creata in design-time, i thread "secondari" non vengano mai eseguiti insieme. Dunque ci sono massimo due thread attivi: quello principale e uno solo fra i secondari.

    Devo dire che piano piano sto imparando a utilizzare i thread e a comprenderne l'utilità, ma una cosa ancora non mi è chiara: l'utilizzo di Synchronize. La documentazione dice:

    Synchronize causes the call specified by Method to be executed using the main thread, thereby avoiding multi-thread conflicts. If you are unsure whether a method call is thread-safe, call it from within the Synchronize method to ensure that it executes in the main thread.
    Se ho capito bene, Synchronize serve ad eseguire un determinato metodo sul thread principale nonostante lo si lanci da un thread secondario. Ma se il thread principale sta già eseguendo una procedura per conto suo, la interrompe per riprenderla in seguito oppure attende che sia terminata e quindi esegue quanto richiesto dal thread secondario?
    In genere per lanciare qualcosa sul thread principale adopero i messaggi.

  7. #7
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,463
    Originariamente inviato da firefox88
    Devo dire che piano piano sto imparando a utilizzare i thread e a comprenderne l'utilità, ma una cosa ancora non mi è chiara: l'utilizzo di Synchronize. [...]
    Il funzionamento di Synchronize è molto semplice. Non fa altro che inserire nella coda dei messaggi dell'applicazione un messaggio specifico, a cui viene allegato l'indirizzo del metodo da eseguire.

    Originariamente inviato da firefox88
    Ma se il thread principale sta già eseguendo una procedura per conto suo, la interrompe per riprenderla in seguito oppure attende che sia terminata e quindi esegue quanto richiesto dal thread secondario?
    Il thread principale è generalmente impegnato a verificare la presenza dei messaggi in coda per l'applicazione e a gestirli; siccome la Synchronize non fa altro che inserire un ulteriore messaggio in coda, questo verrà gestito quando tutti i messaggi precedenti sono stati serviti.

    Originariamente inviato da firefox88
    In genere per lanciare qualcosa sul thread principale adopero i messaggi.
    In tal caso, credo sia molto probabile che tu abbia già implementato qualcosa del tutto simile al meccanismo di funzionamento di Synchronize.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2005
    Messaggi
    247
    In tal caso, credo sia molto probabile che tu abbia già implementato qualcosa del tutto simile al meccanismo di funzionamento di Synchronize.
    Già... E mi sembrava strano che non si potesse fare in altro modo.

  9. #9
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,463
    Originariamente inviato da firefox88
    Già... E mi sembrava strano che non si potesse fare in altro modo.
    Altri modi ci sono: usare Mutex, Critical Section, semafori, ecc.

    Lo strumento più adatto dipende dall'esigenza.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.