Ciao a tutti,
sto studiando la possibile struttura di un programma da realizzare e non voglio perdere l'occasione di chiarirmi un pò di punti: non mi piace far le cose senza capirle!
Premessa: non specifico i parametri che vengono passati ai metodi ma ovviamente li ho messi. Si tratta di una console application, nessun elemento grafico.
Scenario
- Il thread principale del mio programma istanzia N oggetti della classe OBJ1. Ciascuno di questi oggetti contiene un evento definito al suo interno e un metodo DoWork() che poi richiama questo evento passandogli codici diversi a seconda della segnalazione che vuole fare.
- Il thread principale istanzia anche un altro oggetto OBJ2 che dovrà gestire tutta la parte di tracciamento log ed errori, conunicati a lui dalle varie istanze di OBJ1 tramite il loro evento: per far questo associa ad ognuno degli N eventi (uno per ognuna delle N istanze di OBJ1) il metodo LogManagement() dell'istanza di OBJ2 come gestore dell'evento.
- Il thread principale crea e lancia gli N metodi DoWork delle N istanze di OBJ1 in N thread secondari paralleli.
Poi il thread principale sta in wait (questo aspetto non è importante ai fini della discussione) mentre le N elaborazioni parallele fanno il loro.
-> A questo punto mi aspetto che gli N processi secondari possano in parallelo lanciare il loro evento ogni volta che è necessario e in automatico l'oggetto OBJ2 tenga traccia di quanto accade ad esempio scrivendo in un file TXT tutti i messaggi relativi agli eventi sollevati.
Ho però diversi dubbi e vorrei analizzare a fondo la questione, che credo utile e interessante a livello generale. Elenco le mie considerazioni/incertezze aspettando poi dagli altri utenti conferme o smentite.![]()
1) Tutti i thread condividono la stessa area di memoria per cui possono tutti puntare i vari "(s)oggetti" di cui sopra, ovviamente prestando attenzione alle problematiche del multi-thread cioè stando attenti a non accedere mai contemporaneamente a risorse condivise.
In teoria qualsiasi oggetto istanziato in un thread è accessibile dagli altri visto che l'area di memoria è condivisa, giusto?
2) Quando un thread lancia un evento in pratica è come richiamare un delegate cioè un puntatore a funzione: il thread che lancia l'evento salterà dal flusso di istruzioni in cui si trova a quello della funzione che gestisce l'evento e una volta finito riprenderà l'esecuzione del flusso dalla riga successiva a quella che ha scatenato l'evento. Il meccanismo non è quindi asincrono bensì sincrono. Corretto? Inoltre la chiamata dell'evento, e quindi la chiamata della funzione che lo gestisce, comporterà il caricamento nello stack del thread in questione di una copia delle istruzioni da eseguire per cui nel caso in questione avremo potenzialmente N stack (relativi agli N thread) in cui contemporaneamente vi sarà caricata una copia della funzione LogManagement(). Siete d'accordo?
3) A questo punto l'aspetto delicato sarà gestire eventuali accessi da parte di tutte queste repliche parallele del LogManagement() a membri di OBJ2 (che saranno condivisi in quanto l'oggetto è uno solo) o ad esempio ad un file TXT dove si va a scrivere. Siete d'accordo?
Alla luce di queste considerazioni sarei portato a chiedermi che differenza ci sarebbe se invece che usare gli eventi io passassi ad ogni costruttore di OBJ1 (dal thread principale) il puntatore all'oggetto OBJ2 e potessi quindi poi richiamare da ogni thread secondario il metodo LogManagement() direttamente.
Trovo questo scenario interessante come spunto di rilfessione per capire bene come funzionano gli eventi e come uno scenario multi-thread possa farne uso.
Attendo commenti e correzioni alle mie affermazioni...![]()
Grazie