…ancora sulla classe Process (System.Diagnostics)
Della serie: quando ci si aspetta che le cose funzionino in ben altro modo!
In sostanza, quando lanciamo dalla nostra applicazione .Net un altro processo tramite la classe Process, possiamo benissimo “schematizzare” il funzionamento come un thread che controlla l’andamento del programma concorrente.
Consideriamo il seguente codice allora.
OtherProcess = new Process();
OtherProcess.StartInfo.FileName = "OtherProcess.exe";
OtherProcess.StartInfo.Arguments = "/someParameters";
OtherProcess.Exited += delegate(object sender, EventArgs e) { otherProcessTerminated(); };
OtherProcess.EnableRaisingEvents = true;
OtherProcess.Start();
Nella situazione sopra proposta, una volta che l’applicazione OtherProcess.exe termina verrà lanciato l’evento Exited che porterà all’esecuzione del relativo delegate e, per finire, alla chiamata della funzione otherProcessTerminated.
E fin qui nulla da obbiettare. La domanda è: in che modo viene “gestito” l’evento? Mi sarei aspettato che venisse messo in coda e processato ordinatamente (nel Main thread) dopo quanti lo precedevano. In realtà ciò non avviene, ma è lo stesso thread creato appositamente dalla classe Process che si prende in carico anche l’esecuzione del delegate, generando delle “race condition” che portano a side effects quasi mai considerati in fase di sviluppo.
Come poter aggirare la cosa, che risulta assai sgradevole se si è fatto di tutto al fine di evitare problemi di concorrenza? Molto semplice: prima di invocare il metodo Start, aggiungete la seguente linea di codice.
OtherProcess.SynchronizingObject = this;
Ovviamente il puntatore this dovrà far riferimento ad un controllo WindowsForm in grado di “gestire” i messaggi (per dirlo con terminologia Win32).
Qui la documentazione relativa alla proprietà SynchronizingObject della classe System.Diagnostics.Process.
P.s.: per questo post si ringrazia il Sig. Botsutoshi per il suo indispensabile contributo.










