Newsgroup: it.comp.lang.visual-basic
Titolo: Il programma non si chiude!

Ciao
Ho scritto un piccolo applicativo ed ho questo problema.
Su alcuni PC, il programma che dopo aver svolto una stupida funzione di
sposta/copia di alcuni file, non si chiude correttamente ma si "freeza" e
devo andare di ctrl+alt+canc.
Il programma, ripeto, una volta lanciato sposta/copia alcuni file al click
di un command button e poi si "dovrebbe" chiudere.
Avendolo diffuso, alcuni utenti (diciamo 1 su 10) hanno lamentato il
"freeze" dell'applicativo dicendo che questo compie la sua funzione di
copia/sposta e poi invece di uscire si freeza.
Da che parte inizio a cercare, se c'č, l'errore, considerando che svolge il
compito per cui č stato scritto ma, non esce correttamente?

SAP ha scritto:




Per i files, ho l'impressione che necessita intervenire sul file system,
quindi chiedere l'esecuzione a windows. Qualche variabile non chiusa o
ancora in vita ?
Ave
giuseppeD
---
CCR
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 chiusa o ancora in vita ?
Come potrei testare questa cosa?

 [...]
Il form che contiene il pulsante e' a scelta obbligatoria (Form.Show 1)? 
Esci con Unload Me?
Ci sono classi istanziate (Set Pinco = New Palla)?
    Alex

 Ci sono classi istanziate (Set Pinco = New Palla)?
No, nessuna classe istanziata.
Qualche idea?

 Qualche idea?
Mah... ti posso dire come faccio io, non so se in maniera molto scientifica. 
;-)
Butto giu' un esempiuzzo al volo in calce al post.
Vedi tu se ti puo' essere di qualche aiuto o non ci azzecca alcunche'. ;-)
Ciao!
    Alex
'------------------
'Inizio esempiuzzo
'------------------
'
'** Modulo: ModuloPrincipale.bas **
'
'Dichiarazioni
Public mObj as MiaClasse
Public mObjDLLInRef as MiaDLLInRef
'ecc...
'Sub di avvio
'
Sub Main()
Dim idxFileSeq as Integer
Dim strFileSeq as String
    'apro file seq.
    strFileSeq = "c:\.....\MioFile.ppp"
    idxFileSeq = FreeFile
    Open strFileSeq For ... As idxFileSeq
    '
    Set mObj = New MiaClasse
    Set mObjDLLInRef = New MiaDLLInRef
    'carico il form
    Load MioForm
    'imposto eventuali parametri di avvio
    MioForm.Setup par1, par2, ecc.
    'mostro il form a scelta obbligatoria
    MioForm.Show 1 '(o vbModal)
    'quando il form rilascia il controllo, lo scarico,
    'tanto, se anche l'ho gia' scaricato, non causo alcun errore
    Unload MioForm
    '
    'imposto tutto a Nothing
    Set mObj = Nothing
    Set mObjDLLInRef = Nothing
    '
    'chiudo tutti i files aperti
    Close
    'eventualmente, a questo punto, termino il programma brutalmente
    End
    'dopodiche' ho buone probabilita' che non resti nulla di "appeso"
End Sub
'** Form: MioForm.frm **
'sub di avvio del form MioForm
Sub Setup(par1 As Integer, par2 As String, ecc.)
    Me.Label1(0).Caption = CStr(par1)
    Me.Label1(1).Caption = par2
    '...
    'ecc.
    '...
End Sub
'Pulsante di gestione dei files
Private Sub cmdGestisciFiles_Click()
    'Fa quello che deve fare...
    '...
    '...
End Sub
'Pulsante di chiusura: nasconde il form e
'fa ritornare il flusso del programma alla routine di avvio del modulo 
principale
Private Sub cmdEsci_Click()
    Hide
End Sub
'------------------
'Fine esempiuzzo
'------------------

A completamento del discorso accennato (con esempiuzzo) nel mio ultimo post, 
ti spiego brevemente che io faccio in quel modo perche' tempo fa avevo 
riscontrato un comportamento del genere. Non ricordo precisamente il 
perche', ma tempo fa mi era capitato sott'occhio un programma che aveva un 
problema del genere: in un progetto c'era un form a scelta obbligatoria dal 
quale si poteva uscire cliccando su un pulsante che eseguiva un Unload Me; 
dopo l'esecuzione dell'Unload Me, pero', si verificava un qualche evento 
legato al form (oppure c'era una qualche istruzione successiva all'Unload 
Me, ora non ricordo bene) che faceva ricaricare in memoria il form appena 
scaricato... e il programma restava "appeso" in memoria.
Da allora, se ho un form a scelta obbligatoria, ove possibile, cerco di far 
scaricare il form alla stessa routine che ne ha causato il caricamento, come 
ti ho illustrato.
Riciao!
    Alex

Ok, grazie... ora provo.


 ti ho illustrato.
Certo, perchè è una pessima regola scaricare un oggetto da se stesso.
Peggio ancora è fare ad es. un
Unload Form2
da dentro a un'istanza di Form2.
Questo è proprio un errore logico di programmazione che può portare a
disastri inenarrabili.
Inoltre per i form, spece quelli modali che sono proprio di semplice
gestione proprio perchè "si fermano", è buona norma scaricare anche il
codice relativo:
Dim f As Form2
Set f = new Form2
f.Show vbModal
' utilizzo di eventuali proprietà di Form2, come
' ad es. una ipotetica f.DialogResult
Unload f
Set f = Nothing
L'ultima scarica anche tutta la memoria relativa alle variabili pubbliche a
livello di form, che altrimenti rimarrebbero valorizzare al successivo Load.
Tornando al problema iniziale: due cose sono le principali cause di
mantenimento in vita di un programma:
- i form non sono stati tutti scaricati (verificare con Forms.Count)
- un ciclo, magari con un DoEvents in mezzo è ancora attivo anche se tutti i
form sono stati scaricati.
Ciao
--
Reporting tool: 
http://www.neodatatype.net

 form sono stati scaricati.
Bello. :-) Anche a me, comunque, e' capitato e capita di incontrare anomalie 
dovute ad un utilizzo smodato di DoEvents.
Ciao!
    Alex

 Ciao
Ringrazio entrambi per le dritte, sono un novizio per cui starà sicuramente
commetendo qualche errore logico di programmazione.
Sto facendo dei tentativi, vani purtroppo.
Il codice è strutturato così:
Dichiarazioni delle variabili
Dim .... as string
Private Sub Form_Load()
form.Show <----- DA QUELLO CHE HO CAPITO E' SICURAMENTE ERRATO
... serie di operazioni
End sub
Private Sub Avvia_Click()
...serie di istruzioni
Unload form
End Sub
Come dovrei correggere?
Sto provando quanto segue senza esito:
Dichiarazioni delle variabili
Dim .... as string
Sub main()
form.Show
end sub
Private Sub Form_Load()
... serie di operazioni
End sub
Private Sub Avvia_Click()
...serie di istruzioni
Unload form
End Sub
Grazie, ciao

 [...]
Dipende da cio' che intendi ottenere: se cio' che ti serve e' un form
"modale" che attenda un input da parte dell'utente, il codice e' circa
quello che ho gia' postato.
Se modifichi il codice e non ottieni quello che ti aspetti (per esempio, se
aggiungi al progetto un modulo che contenga una sub Main che esegue il
caricamento del form), tieni conto che devi accedere alle proprieta' del
progetto per cambiare l'oggetto di avvio.
Se non sai come funziona, puoi fare questa prova:
- crea un nuovo progetto (il progetto nuovo, come avrai senz'altro visto, 
viene creato con un form vuoto che si chiama Form1);
- fai un click destro sulla finestra di progetto e seleziona la voce 
"Inserisci -> Modulo", quindi aggiungi un nuovo modulo che avra' come nome 
predefinito "Module1";
-  nel modulo "Module1" aggiungi una routine che abbia il seguente codice:
Sub Main()
    MsgBox "Eseguo la routine di avvio"
End Sub
- facendo un doppio click sul form, ti troverai nella procedura che gestisce 
l'evento di caricamento del form e vi fai la seguente aggiunta:
Private Sub Form_Load()
    MsgBox "Ho caricato il form Form1"
End Sub
- a questo punto premi F5, avvi il programma e vedi cosa succede.
Fatta questa prova, prova a modificare l'oggetto di avvio dalle proprieta' 
del progetto:
- dal menu "Progetto", seleziona la voce "Proprieta' di Progetto1" 
(Progetto1 e' il nome predefinito del progetto nuovo);
- nella finestra che raggruppa le proprieta' del progetto, sotto la voce 
"Generale", in alto a destra c'e' una combobox contrassegnato dall'etichetta 
"Oggetto di avvio"; l'oggetto di avvio predefinito e' "Form1": cio' 
significa che all'avvio del programma, come prima cosa sara' caricato il 
form;
- aprendo l'elenco, seleziona "Sub Main";
- conferma con "OK", quindi premi nuovamente F5 per eseguire il programma e 
vedi se succede qualcosa di diverso.
Giunto a questo punto, puoi fare un paio di altre prove per cominciare a 
capire cosa comporta l'utilizzo di un form "modale".
Se tu, da una subroutine, carichi e mostri un form, normalmente il codice 
prosegue oltre all'interno della subroutine fino alla fine della stessa.
Puoi modificare la Sub Main come di seguito:
Sub Main()
dim idx as Integer
    idx = 0
    Load Form1
    Form1.Show
    idx = 150
    MsgBox "La variabile idx vale " & cstr(idx)
End Sub
Prova ad eseguire il programma e ad interromperlo chiudendo il form.
Vedrai che, in questo modo, immediatamente dopo il caricamento e la 
visualizzazione del form, alla variabile idx viene assegnato il valore 150 e 
viene mostrato il msgbox, quindi il flusso del programma, all'interno della 
routine, ha termine, ma il form rimane attivo.
Altro esempiuzzo:
Sub Main()
dim idx as Integer
    idx = 0
    Load Form1
    Form1.Show 1
    idx = 150
    MsgBox "La variabile idx vale " & cstr(idx)
    Unload Form1
End Sub
Nota quell'"1" passato come parametro allo "Show" (potresti utilizzare la 
costante vbModal al suo posto con lo stesso risultato, giacche' tale 
costante vale, x l'appunto, 1): quello e' cio' che serve per rendere 
"modale" (o a scelta obbligatoria) il tuo form.
Ancora una volta, prova ad eseguire, chiudi il form e vedi un po' che 
succede.
In questo secondo caso, dopo il caricamento e la visualizzazione del form, 
il controllo del programma passa al form e l'esecuzione delle istruzioni 
all'interno della sub Main si interrompe in attesa delle operazioni da parte 
dell'utente sul form caricato; una volta che l'utente avra' chiuso il form, 
sara' eseguita l'assegnazione alla
variabile e la visualizzazione del messaggio.
Fatto questo, puoi rivedere gli altri esempiuzzi postati da me e da Zanna 
che, evidentemente, ci capisce ben piu' di me. :-)
Non conoscendo di preciso il resto del codice del tuo programma, non 
garantisco che la soluzione del tuo problema stia effettivamente qui, nel 
caricamento/scaricamento del form, comunque capire come funziona e' sempre 
cosa molto buona. ;-)
Non so se sono stato sufficientemente chiaro.
Riciao! ;-)
    Alex

> [...]
Credo di si, faccio delle prove...
Grazie del supporto.
Ciao

     Alex
Niente non riesco a rimediare e sta crescendo il numero di utenti che hanno
il problema di chiusura del programma.
Alexx, non è che saresti disposto a dargli un'occhiatina? Sono poche righe
di codice, ma sono troppo imbranato ed niubbio per cavarci fuori le gambe.
Grazie comunque, ciao.

 [...]
Scusa se non ti ho risposto subito, ma sono stato un po' preso e il tuo post
mi e' sfuggito. Poi la scorsa settimana sono stato in ferie.
Quello che mi veniva in mente circa il tuo problema te l'ho gia' scritto. Se
vuoi scrivermi in privato, la mia mail e' valida. Non ti garantisco, pero',
tempi di risposta rapidi.
Comunque spero che, nel frattempo, tu sia riuscito a cavartela:
probabilmente si trattava di una sciocchezza.
Ciao!
    Alex