Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [Delphi] Eventi customizzati

    Una classe instanzia un certo numero di thread. Questa classe, qualora si verifichi una tale situazione genera un evento all'interno di ogni thread. I thread quindi correttamente eseguono alcune cose.
    Il mio problema è che fintantoché tutti i thread non hanno finito di eseguire la procedura invocata dall'evento, la classe principale non restituisce il controllo all'utente.
    Io invece ho la necessità che generato l'evento ogni thread possa eseguire le proprie operazioni senza che l'utente debba attenderne il completamento.
    E' possibile? Posto del codice:

    Classe base, procedura che genera gli eventi all'interno di ogni thread:
    codice:
      for I := ListaThread.Count - 1 downto 0 do begin
        if Assigned(TThTerminaleServer(ListaThread[I])) then begin
          TThTerminaleServer(ListaThread[I]).AggionaBacheca(self);
        end;
      end;
    Thread:
    codice:
    type
      TNotifyEvent= procedure(Sender: TObject) of object;
    ...
          EAggionamentoBacheca: TNotifyEvent;
        published
          property OnAggionamentoBacheca: TNotifyEvent read EAggionamentoBacheca write EAggionamentoBacheca;
    ...
    constructor
      EAggionamentoBacheca:= AggionamentoBacheca;
    ...
    procedure TThTerminaleServer.AggionamentoBacheca(Sender: TObject);
    begin
      ...
    end;
    Fintantoché la lista "ListaThread" viene percorsa completamente l'utente deve aspettare.
    Come posso fare?
    Ho commesso qualche errore?

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301

    Re: [Delphi] Eventi customizzati

    Originariamente inviato da denis76
    Questa classe, qualora si verifichi una tale situazione genera un evento all'interno di ogni thread.
    Cosa significa esattamente "genera un evento all'interno di ogni thread"?
    Il metodo assegnato per l'evento viene eseguito nel contesto della classe, nel contesto del thread o nel thread primario dell'applicazione?

    Originariamente inviato da denis76
    Il mio problema è che fintantoché tutti i thread non hanno finito di eseguire la procedura invocata dall'evento, la classe principale non restituisce il controllo all'utente.
    Io invece ho la necessità che generato l'evento ogni thread possa eseguire le proprie operazioni senza che l'utente debba attenderne il completamento.
    E' possibile?
    Se l'esecuzione del metodo che risponde all'evento viene delegato ad un thread, esso verrà eseguito dal thread.

    Originariamente inviato da denis76
    codice:
      for I := ListaThread.Count - 1 downto 0 do begin
        if Assigned(TThTerminaleServer(ListaThread[I])) then begin
          TThTerminaleServer(ListaThread[I]).AggionaBacheca(self);
        end;
      end;
    Se la classe che gestisce i thread esegue questo codice, significa che il ciclo avviene in modo sincrono all'applicazione; se avviene in un thread secondario, sarà questo a dover attendere la fine delle operazioni, come effettivamente riscontrato. Si deve creare un thread secondario per ciascun metodo da eseguire, delegando a ciascuno il compito di effettuare le operazioni del caso in un contesto separato.

    Non ho comunque compreso bene la struttura con cui abbiamo a che fare; eventualmente, descrivi meglio il panorama, cioè le finalità d'uso dell'architettura, il motivo per cui sono state scritte e quello che si vuole ottenere in termini pratici.

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

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

  3. #3
    Bene, ora mi spego meglio.
    Il programma si collega e rimane collegato contemporaneamente con un certo numero di terminali collegati via ip. Ogni terminale è a sua volta coltrollato da un thread generato dal programma principale. Tale thread si preoccupa di ricevere dei dati dai terminali e di elaborali. L'elenco dei thread è contenuto in una lista che ho chiamato ListaThread.
    In acluni casi l'utente deve inviare degli ordini a tutti i terminali. Per fare questo io dal form principare eseguo:

    codice:
      for I := ListaThread.Count - 1 downto 0 do begin
        if Assigned(TThTerminaleServer(ListaThread[I])) then begin
          TThTerminaleServer(ListaThread[I]).AggionaBacheca(self);
        end;
      end;
    La funzione "AggionaBacheca(self);" contenuta in ogni thread non fa altro che generare un evento all'interno del thread stesso in questo modo:
    codice:
      if Assigned(EAggionamentoBacheca) then OnAggionamentoBacheca();
    L'evento customizzato nel thread è così composto:
    codice:
    type
      TNotifyEvent= procedure(Sender: TObject) of object;
    ...
          EAggionamentoBacheca: TNotifyEvent;
        published
          property OnAggionamentoBacheca: TNotifyEvent read EAggionamentoBacheca write EAggionamentoBacheca;
    ...
    constructor
      EAggionamentoBacheca:= AggionamentoBacheca;
    ...
    procedure TThTerminaleServer.AggionamentoBacheca(Sender: TObject);
    begin
      ...
    end;
    Quando viene dato il comando dall'utente effettivamente viene correttamente percorsa la lista, viene generato un evento all'interno di ogni thread, il thread manda correttamente i dati al proprio terminale.
    La cosa però si verifica in modo ciclico, in sequenza dal primo all'ultimo thread. Io invece ho bisogno che l'utente dia il comando ed i thread inviino i dati in parallelo restituendo subito il controllo dell'applicazione all'utente senza quindi che l'utente debba attendere che la sequenza sia terminata.

  4. #4

  5. #5
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301
    A mio avviso, è l'architettura generale dell'applicazione ad essere sbagliata.

    Ciascun thread svolge, in modo asincrono, una o più operazioni, e ovviamente durante il processo non può farsi carico di nuove richieste di elaborazione.

    Nel caso in esame, vengono creati n thread, ma alla fine il loro lavoro - se ho capito bene - è stato demandato ad un unico thread, che li gestisce, ed è quest'ultimo a svolgere le operazioni richieste, non i singoli thread.

    Se le operazioni di gestione di ciascun terminale devono essere svolte allo stesso tempo, allora tali operazioni vanno delegate a thread separati; la classe "unificatrice", tutt'al più, può fornire funzionalità di gestione complessive, ad esempio intimando ai singoli thread di terminare oppure restituendo informazioni sullo stato dei lavori, ma non può farsi carico del lavoro stesso dei singoli thread, e se lo fa chiaramente potrà elaborarne solo uno alla volta, da qui l'inutilità di avere thread separati.

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

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

  6. #6
    In generale questo è un problema di ogni sistema operativo (in quanto si utilizzano i thread).

    Ora: o crei un thread principale dove vai a "sincronizzare" i thread con i vari eventi (magari utilizzando i puntatori linkando i thread secondari agli eventi del thread principale;
    Oppure utilizzi dei mutex e delle Tcritical section.

    Potresti anche suddividere i compiti ai vari thread, o anche vedere gli esempi che borland fornisce sui thread nella sezione demo.

    Cià!

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 © 2024 vBulletin Solutions, Inc. All rights reserved.