Italian Funzionamento di Wait For

MARCO CORRIAS

Active Member
Licensed User
Buongiorno ,
sto utilizzando wait for , per esser certo che il download di una serie di file sia completa.
Ho preso spunto dal seguente esempio. Tutto OK funziona.

B4X:
Sub DownloadFolder (ServerFolder As String)
   FTP.List(ServerFolder)
   Wait For FTP_ListCompleted (ServerPath As String, Success As Boolean, Folders() As FTPEntry, Files() As FTPEntry) '<----
   If Success Then
     For Each f As FTPEntry In Files
         FTP.DownloadFile(ServerPath & f.Name, False, File.DirApp, f.Name)
         Wait For FTP_DownloadCompleted (ServerPath2 As String, Success As Boolean) '<-----
         Log($"File ${ServerPath2} downloaded. Success = ${Success}"$)
     Next
   End If
   Log("Finish")
End Sub

Non ho però chiaro come il comando wait for ... capisce dove termina il suo lavoro .
Nel specifico :
chi dice a wait for che deve svolgere il lavoro sino al comando
B4X:
Log($"File ${ServerPath2} downloaded. Success = ${Success}"$)
e poi ... terminato l'evento wait for ... svolge il next del ciclo (for) ?

per farla breve ... dopo il log
posso inserire altro codice ( es: if then else )
in modo tale da capire se le variabili
ServerPath2 As String, Success As Boolean
hanno ancora valore , oppure sono già fuori dal FTP_DownloadCompleted ?

Grazie
 

LucaMs

Expert
Licensed User
chi dice a wait for che deve svolgere il lavoro sino al comando
Attende un evento. Nell'esempio l'evento è FTP_DownloadCompleted, che viene "scatenato" dalla libreria FTP appunto a fine download.

Potresti, ad esempio (per chiarire) avere una tua routine:

Sub AAA
' qui fa qualcosa
CallSubDelayed(Me, "FineDellaRoutineAAA")
End Sub

ed usare:
AAA ' <--- lancia AAA
Wait For FineDellaRoutineAAA


e poi ... terminato l'evento wait for ... svolge il next del ciclo (for) ?
Sì. In pratica (sempre l'esempio) lancia l'esecuzione di un download, RESTITUISCE la "esecuzione" alla routine chiamante (quella che ha chiamato la DownloadFolder) e ritorna alla riga successiva al WaitFor quando il download (l'evento FTP_DownloadCompleted, più precisamente) sia stato completato, per cui viene eseguito il Log e poi il Next.

per farla breve ... dopo il log
posso inserire altro codice ( es: if then else )
in modo tale da capire se le variabili
ServerPath2 As String, Success As Boolean
hanno ancora valore
Sì.
 

MARCO CORRIAS

Active Member
Licensed User
Grazie LucaMs,
un ultima cosa per conferma

posso fare quindi una cosa del genere ?

B4X:
 For i = 0 To listafileCsv.Size    -1
    nFile =listafileCsv.Get(i)
           
    FTP.DownloadFile(percorso & nFile , False, File.DirRootExternal & "/" & dirCreate & "/", nFile )
        ScaricaFile
          Wait For FineDellaRoutineAAA
          Log("ftp download :" & i    )      
 Next

'****************************
'****************************
Sub ScaricaFile

  FTP_DownloadCompleted (ServerPath As String, Success As Boolean)
        Log(ServerPath & ", Success=" & Success)
            If Success = False Then
                Log(LastException.Message)
            End If
    Log("ftp download :" & i    )

  CallSubDelayed(Me, "FineDellaRoutineAAA")
End Sub
Grazie
 

LucaMs

Expert
Licensed User
posso fare quindi una cosa del genere ?
Lo fa già la routine che hai pubblicato nel primo post, con la differenza (vedo... senza vedere, guardando "Il commissario Montalbano" :D) che tu usi una tua lista, anziché prelevarla tramite FTP.

B4X:
For i = 0 To listafileCsv.Size -1
    nFile = listafileCsv.Get(i)
    FTP.DownloadFile(percorso & nFile, False, File.DirRootExternal & "/" & dirCreate & "/", nFile )
    Wait For FTP_DownloadCompleted (ServerPath As String, Success As Boolean)
    If Success Then
        Log(nFile & " scaricato regolarmente")
    Else
        Log("Scaricamento " & nFile & " fallito")
    End If
 Next
Nota che non mi convince la costruzione della Directory locale (GetSafeDirDefaultExternal)
 
Last edited:

MARCO CORRIAS

Active Member
Licensed User
Lo fa già la routine che hai pubblicato nel primo post, con la differenza (vedo... senza vedere, guardando "Il commissario Montalbano" :D) che tu usi una tua lista, anziché prelevarla tramite FTP.

B4X:
For i = 0 To listafileCsv.Size -1
    nFile = listafileCsv.Get(i)
    FTP.DownloadFile(percorso & nFile, False, File.DirRootExternal & "/" & dirCreate & "/", nFile )
    Wait For FTP_DownloadCompleted (ServerPath As String, Success As Boolean)
    If Success Then
        Log(nFile & " scaricato regolarmente")
    Else
        Log("Scaricamento " & nFile & " fallito")
    End If
 Next
Nota che non mi convince la costruzione della Directory locale (GetSafeDirDefaultExternal)

La lista
listafileCsv.Get(i)
è stata popolata in precedenza tramite ftp.List ... perchè devo filtrare alcuni file ... e non inviarli tutti quelli presenti nella cartella.
Grazie
 

MARCO CORRIAS

Active Member
Licensed User
Nota che non mi convince la costruzione della Directory locale (GetSafeDirDefaultExternal)
parli delle directory che io chiamo
dirCreate ???

Nel caso , ovviamente all'inizio chiedo autorizzazione alla creazione
B4X:
    rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        Msgbox("Funzionamente App" & CRLF & "Sono necessarie autorizzazioni ","Attenzione")
            MsgboxAsync("No permission to access external storage", "Action permission")
    End If
 

sirjo66

Well-Known Member
Licensed User
chi dice a wait for che deve svolgere il lavoro sino al comando
Log($"File ${ServerPath2} downloaded. Success = ${Success}"$)
e poi ... terminato l'evento wait for ... svolge il next del ciclo (for) ?
Stai facendo un po' di confusione
Il comando Wait For serve proprio per arrestare il programma in quel punto fino a che ....... e decidi tu fino a quando
FTP.DownloadFile serve per far partire il download del file, poi la riga
Wait For FTP_DownloadCompleted dice già tutto, e cioè "attendi finchè il download è completato" e quindi poi proseguirà con
Log($"File ${ServerPath2} downloaded. Success = ${Success}"$)
ma solo dopo aver completato il download
Non devi esser tu a chiamare FTP_DownloadCompleted, verrà chiamato in automatico dall'oggetto FTP quando il download è concluso, il Wait For infatti sta lì ad aspettare che la routine FTP_DownloadCompleted sia stata chiamata e che abbia terminato il suo lavoro
 

LucaMs

Expert
Licensed User
Stai facendo un po' di confusione
Il comando Wait For serve proprio per arrestare il programma in quel punto fino a che ....... e decidi tu fino a quando
FTP.DownloadFile serve per far partire il download del file, poi la riga
Wait For FTP_DownloadCompleted dice già tutto, e cioè "attendi finchè il download è completato" e quindi poi proseguirà con
Log($"File ${ServerPath2} downloaded. Success = ${Success}"$)
ma solo dopo aver completato il download
Non devi esser tu a chiamare FTP_DownloadCompleted, verrà chiamato in automatico dall'oggetto FTP quando il download è concluso, il Wait For infatti sta lì ad aspettare che la routine FTP_DownloadCompleted sia stata chiamata e che abbia terminato il suo lavoro
Non è esattamente così (@sirjo66 ovviamente lo sa ma quanto ha scritto potrebbe non rendere esattamente bene la cosa).
Il programma NON si arresta in quel punto, continua ad essere elaborato/eseguito nella routine che ha chiamato quella che contiene il wait for, ma rientra in quest'ultima nella riga successiva al Wait For quando la "condizione" del wait for diventa vera, ovvero, in questo caso, al termine del download DI UN file.


parli delle directory che io chiamo
dirCreate ???
no, parlo di tutta la dir che passi al comando ftp, che comprende la dirCreate ma è composta in questo modo:

File.DirRootExternal & "/" & dirCreate & "/"

Se non è proprio indispensabile che i file vengano salvati nella Root, molto meglio usare la DirInternal.
Se invece lo è... va bene aver chiesto il permesso ma, dicevo "a occhio", non so se la costruzione vada bene o sia necessario usare invece File.Combine (se il tutto ti funziona, nessun problema, ovviamente).
 
Top