Autore Topic: Bloccare i processi in corso  (Letto 732 volte)

Offline akrobaticone

  • Gran Maestro dei Gamberi
  • *****
  • Post: 983
    • Mostra profilo
Bloccare i processi in corso
« il: 03 Marzo 2017, 11:41:29 »
Ho un problema
Nel mio progetto sono in ascolto sulla porta seriale, un timer funziona da timeout se non arriva nulla sulla porta
l'evento timer chiamato provoca la chiusura del form nel quale la seriale sta lavorando, le funzioni che erano state chiamate prima dell'evento  vengono comunque terminate e questo mi crea qualche errore
Almeno credo sia questo il problema
La domanda forse è strana, ma posso istantaneamente bloccare e terminare tutti i processi in corso e provocare la chiusura del form?
"e il naufragar m'è dolce in questo mar"

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #1 il: 03 Marzo 2017, 14:50:08 »
La domanda forse è strana, ma posso istantaneamente bloccare e terminare tutti i processi in corso e provocare la chiusura del form?

Tre domande:
1) quanti sono i processi in corso?
2) chi genera questi processi in corso, e quindi che rapporto di parentela vi è fra il programma principale e tali processi in corso ?
3) che rapporto funzionale vi è tra il programma principale e tali processi in corso ? A che servono per il programma principale?
« Ultima modifica: 03 Marzo 2017, 15:31:59 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline akrobaticone

  • Gran Maestro dei Gamberi
  • *****
  • Post: 983
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #2 il: 03 Marzo 2017, 16:04:06 »
Ok
mi spiego meglio

il programma sfrutta una macchina a stati finiti all'interno di un evento timer
con una select case seleziono i vari stati della macchina
all'interno di questo ciclo leggo la seriale e se non arriva risposta in tempo scatta un altro timer che fa da timeout
al momento sto sfruttando un flag chiamato allarme che diventa true e che va a bloccare nuove letture della seriale e metto lo stato della macchina in una condizione di "parcheggio"  (condizione ALLARME)
il problema è che, una volta finito il codice dell'evento timeout il programma va avanti da dove era rimasto e dati non coerenti o la lettura della seriale sfuggita al blocco possono generare errore

Mi chiedevo se era possibile, direttamente nell'evento timeout chiudere il form e non fare eseguire il resto del codice che è contenuto nella macchina stati finiti
Ho provato a mettere un me.close, ma naturalmente non funziona
in fondo l'evento timer si comporta in questo caso come una sorta di interrupt
Il programma ora gira su Raspberry e mi serve per controllare un bagno di taratura, scarico il programma e (dopo averlo purgato da mille correzioni e strafalcioni) lo posterò quì
Al momento con mille artifizi sono riuscito a farlo funzionare, ma non escludo condizioni particolari che lo possano bloccare di nuovo
Il bagno va di notte e sarebbe spiacevole che si blocchi su temperature estreme
 
"e il naufragar m'è dolce in questo mar"

Offline akrobaticone

  • Gran Maestro dei Gamberi
  • *****
  • Post: 983
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #3 il: 03 Marzo 2017, 17:29:31 »
aggiornamento
il programma mi dava errore poichè rimaneva imprigionato un loop che controllava la correttezza della stringa ricevuta, è bastato mettere la condizione di uscita con allarme=true
le restanti condizioni sparse per il codice sembrano non più necessarie (il venerdi pomeriggio si dovrebbe tornare a casa prima....)
rimane comunque la questione di cui sopra, cioè
avvenuto l'evento timer posso uscire dal form in cui sono immediatamente senza che le parti di codice ancora in esecuzione debbano terminare?

"e il naufragar m'è dolce in questo mar"

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #4 il: 03 Marzo 2017, 18:07:44 »
Sparo la mia idiozia:
E se ogni tanto nel codice delle funzioni controlli se l'allarme è suonato (es. if allarme.suonato then return)?
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #5 il: 03 Marzo 2017, 19:32:01 »
Seconda:
Anche una cosa così...
Codice: [Seleziona]
' Gambas class file

Private pippo As Boolean

Public Sub Form_Open()

  Me.Show
  ' Attivo la funzione
  funzione()

End

Public Sub Form_Close()
 
  pippo = True
 
End

Private Sub funzione()
 
  While pippo = False ' Se si chiude la finestra si interrompe la funzione
    Wait 0.2
    Print "pippo"
  Wend
 
End
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #6 il: 03 Marzo 2017, 20:54:48 »
Non mi è ancora ben chiara la cosa...   


va a bloccare nuove letture della seriale 
Come avviene il blocco della lettura della seriale ? Ossia con quale comando ?



...chiudere il form e non fare eseguire il resto del codice
Ho provato a mettere un me.close, ma naturalmente non funziona
 
La chiusura del Form significa che il processo del programma viene terminato ? Insomma il programma viene arrestato ?

Perché "naturalmente" non funziona con Me.Close ?
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline akrobaticone

  • Gran Maestro dei Gamberi
  • *****
  • Post: 983
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #7 il: 04 Marzo 2017, 10:57:18 »
Codice: [Seleziona]
Public Function ricevi() As String

  Dim s As String = ""
  Dim str As String = ""

  Do
    Wait
    if (allarme=false) then Read #serialport1, str, Lof(serialport1)
    s = s & str
  Loop Until (str <> Chr(13) Or allarme = True)
  If allarme Then
    Return MCost.SERIAL_TIMEOUT
  Else
    Return s
  Endif

End

il loop riceve i caratteri dalla seriale finchè non arriva il fine stringa o si verifica i timeout
la lettura della seriale viene bloccata se allarme è true


Codice: [Seleziona]
Public Sub tmr_timeout_Timer()

  Dim m As Integer

  tmr_macchina.enabled = False               ' ferma il timer della macchina a stati finiti
  m = Message.Error("Errore timeout seriale", "Riprova", "Abbandona")
  If m = 1 Then
    tmr_macchina.enabled = True
  Else
    allarme = True
    Me.close
  Endif

End

il verificarsi del timeout interrompe il loop di controllo della seriale, ma nonostante che termini con me.close la funzione ricevii() prosegue e restituisce il controllo al ciclo che l'ha chiamata

in
Codice: [Seleziona]
Form_Close()
Serialport1.close()
end

per qualche motivo avveniva una nuova lettura -trasmissione sulla seriale che era già chiusa

il programma ora funziona, come detto prima si bloccava nel  loop chiamante la lettura della seriale prima che avvenisse la chiusura del form, è bastato mettere nella condizione di uscita anche  allarme= true

il dubbio però mi è rimasto
è possibile chiudere immediatamente il form all'interno dell'evento timeout senza che nessuna altra istruzione venga eseguita?

Il form è stato aperto da un altro form principale in modalotà showmodal()

Il progetto lo devo sistemare e rendere leggibile, l'ho sviluppato su raspberry con il display 7" e a furia di correzioni e modifiche è un "po" incasinato , lo sistemo e lo condivido

 
"e il naufragar m'è dolce in questo mar"

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #8 il: 04 Marzo 2017, 15:11:38 »
il dubbio però mi è rimasto
è possibile chiudere immediatamente il form all'interno dell'evento timeout senza che nessuna altra istruzione venga eseguita?
......
Il form è stato aperto da un altro form principale in modalotà showmodal()

Quindi tu vuoi chiudere solo questo Form secondario (utilizzato per la lettura della seriale), ma senza terminare l'applicazione principale ?
« Ultima modifica: 04 Marzo 2017, 15:20:33 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #9 il: 04 Marzo 2017, 15:38:38 »
Io ho capito così:

C'è una form (show modal) che quando da una certa porta seriale smettono di arrivare dati, deve chiudere la porta e deve chiudersi terminando le funzioni attive.
Evidentemente tali funzioni lavorano come una sorta di loop o timer altrimenti non vedo come potrebbero sopravvivere alla chiusura della form.

Se così è a me pare di aver già risposto. Non basta chiudere la porta, prima occorre avvisare le funzioni che naturalmente devono saper leggere l'avviso (basta un boolean).
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #10 il: 04 Marzo 2017, 16:42:28 »
Va detto, inoltre, che l'apertura di un secondo Form, seppure come Modal, non genera un nuovo processo attivo, differenziato rispetto a quello dell'applicazione.


« Ultima modifica: 05 Marzo 2017, 14:26:09 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.724
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #11 il: 04 Marzo 2017, 18:11:14 »
...e se tu chiudi immediatamente ?

Codice: [Seleziona]
......

  Do
    Wait
    if allarme=false then Read #serialport1, str, Lof(serialport1)
    s = s & str
  Loop Until (str <> Chr(13) Or allarme = True)

     serialport1.Close

  If allarme Then
    Return MCost.SERIAL_TIMEOUT
  Else
    Return s
  Endif

End

(ovviamente devi poi eliminare la procedura Form_Close( ) .
« Ultima modifica: 04 Marzo 2017, 18:15:29 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline akrobaticone

  • Gran Maestro dei Gamberi
  • *****
  • Post: 983
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #12 il: 05 Marzo 2017, 09:06:51 »
Io ho capito così:

C'è una form (show modal) che quando da una certa porta seriale smettono di arrivare dati, deve chiudere la porta e deve chiudersi terminando le funzioni attive.
Evidentemente tali funzioni lavorano come una sorta di loop o timer altrimenti non vedo come potrebbero sopravvivere alla chiusura della form.

Se così è a me pare di aver già risposto. Non basta chiudere la porta, prima occorre avvisare le funzioni che naturalmente devono saper leggere l'avviso (basta un boolean).

@Gianluigi
alla fine la soluzione è proprio questa
il timer timeout si comporta come una sorta di interrupt, l'unica soluzione è quella di usare la booleana allarme piazzata nei posti critici del codice (che in effetti sono timer e loop)  per evitare che dati anomali o la porta seriale vengano utilizzati dopo il timeout
in fondo il problema mio era solo una questione di ottimizzazione dei loop, credo inoltre di aver capito che non è possibile e forse non ha nemmeno senso avere una funzione che all'istante chiude il form alla stregua di un interruttore ON-OFF senza in qualche modo concludere quello che era in corso
@Vuott
alla stregua di quanto detto sopra, se ben gestito l'allarme, la seriale si può chiudere alla chiusura del form

L'altra eventualità è l'improvvisa disconnessione del convertitore USB-RS232, ma l'unico modo di gestirla è catturare l'errore che si genera evitando che porti al blocco del programma
Appena riesco provo a buttare giù un programma di esempio di gestione seriale, così magari possiamo discutere su qualche cosa di concreto

Grazie



 



"e il naufragar m'è dolce in questo mar"

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.244
  • Tonno verde
    • Mostra profilo
Re:Bloccare i processi in corso
« Risposta #13 il: 05 Marzo 2017, 13:36:16 »

Appena riesco provo a buttare giù un programma di esempio di gestione seriale, così magari possiamo discutere su qualche cosa di concreto
Grazie


Grazie a te! Questa sarebbe una gran cosa, molto utile a tutti  :D  :ok:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro