Guardando meglio, col Wait For non stai attendendo il completamento della routine StopSophosClient scritta là sotto, ma evidentemente una copia che si trova nell'oggetto
GL.oConn.
Dato che quella routine è una Resumable, l'oggetto che la contiene non è da inserire in un modulo di codice, visto che questi non possono gestire eventi.
Quindi oConn va dichiarato, inizializzato e usato altrove, in un'altra B4XPage o nella B4XMainPage.
Perché poi serva un Intent non ne ho idea, visto che non conosco quella classe.
P.S. Mi era venuto un dubbio. E' vero che i moduli di codice non possono gestire eventi (in B4J sì) ma se hanno un oggetto pubblico il quale "esponga eventi"? E in effetti ho verificato, questo è possibile.
Confermo, però quanto scritto sopra; scrivendo, come hai fatto:
Private Sub btnExit_Click
Log1 ("Uscita")
btnStart.Enabled=False
btnExit.Enabled=False
GL.bVPNstarted=False
Wait For (GL.oConn.StopSophosClient) complete ' questa genera l'effetto sgradevole
' Gl.oConn è un'istanza di una classe dichiarata in un modulo GL dove ho le variabili globali
ToastMessageShow("VPN disconnessa",False)
B4XPages.ClosePage(Me)
End Sub
Sub StopSophosClient As ResumableSub
Dim i As Intent
i.Initialize(i.ACTION_MAIN, "")
i.SetComponent("de.blinkt.openvpn/.api.DisconnectVPN")
i.PutExtra("de.blinkt.openvpn.shortcutProfileName", "VPN_Telecontrollo")
StartActivity(i)
ToastMessageShow("Disconnessione VPN in corso...",False)
Sleep(2000)
End Sub
la routine StopSophosClient scritta qui non viene eseguita, viene eseguita quella nell'oggetto oConn dichiarato nel modulo di codice Gl, quindi è in quella che dovresti mettere lo Sleep, è quella che lancia l'Intent e per attendere quei 2 secondi dovresti chiamarla con il Complete(NomeVariabile As TipoVariabile restituito dalla StopSophosClient). E' chiaro che l'Intent partirebbe subito, visto che lo Sleep lo esegui dopo.