Sì, ti manca sicuramente qualcosa . In genere, Gotos viene utilizzato, come hai detto, per eseguire un trasferimento di controllo unidirezionale.
Tuttavia, gli eventi non lo fanno. Quando il codice attiva l'evento, sa perfettamente che una volta che l'evento è stato pubblicato (o elaborato, accodato, attivato ... ecc.) L'esecuzione del codice riprenderà sulla riga successiva del codice che ha generato l'evento.
L'uso di goto crea un accoppiamento molto stretto tra il codice che chiama quell'istruzione e il codice che si trova sul lato ricevente. Lo sviluppatore deve avere una conoscenza approfondita di entrambi i luoghi per poter utilizzare goto.
D'altra parte, il codice che genera eventi normalmente non conosce o interessa chi è interessato ad ascoltare quell'evento. Lì potrebbe essere un ascoltatore. Oppure potrebbero esserci 100 ascoltatori o 0. Questi ascoltatori potrebbero trovarsi nello stesso programma in cui è stato attivato l'evento, oppure potrebbero trovarsi in un'applicazione completamente diversa oppure potrebbero trovarsi su una macchina diversa. Per quanto riguarda l'editore, non appena genera l'evento il suo lavoro è finito.
Se sei con me finora, quello che ho descritto sopra è il caso ideale di pattern pub / sub. Purtroppo nel mondo reale le cose non sono sempre ideali e ci sono casi in cui gli editori generano un evento, un sottoscrittore viene invocato, cambia un intero gruppo di stati e l'esecuzione del codice temporale ritorna all'editore "il mondo" sembra avere stato capovolto. E sono sicuro che vi siete imbattuti in questo in passato, perché questa condizione si verifica spesso quando il pattern pub / sub viene implementato in modo molto semplice (ad esempio tramite l'uso di delegati o eventi in C #, o i puntatori funzione / interfaccia in C / C ++).
Ma questo problema non è necessariamente un modello pub / sub, ma piuttosto l'implementazione di esso. Questo è il motivo per cui molti sistemi fanno affidamento sulle code in modo che quando un evento viene pubblicato, viene semplicemente messo in coda per essere invocato in seguito dando al publisher la possibilità di terminare l'esecuzione mentre il mondo è ancora intatto. Quando l'editore ha finito di fare il suo lavoro, un ciclo degli eventi (noto come "dispatch loop") farà scoppiare gli eventi e invocherà gli abbonati.