PROBLEMA [Visual Basic] Backup di file: calcolo tempo residuo e velocità di trasferimento

money95

Nuovo Utente
17
0
Ciao a tutti!
Devo aggiungere ad un mio software scritto in VB un funzionalità di backup dei dati, ma ho qualche problema. Il processo di copia con relativa progressbar funziona e riesco pure a mostrare la quantità di dati copiati. Però vorrei riuscire a mostrare anche il tempo residuo alla fine della copia e la velocità di trasferimento ma il mio codice non funziona.
Per quest'ultimo problema, ho fatto così: tramite un Timer incremento ad ogni Tick (di 1 sec) la variabile TimeElapsed, poi dopo la copia di ogni file calcolo la velocità facendo TransferRate = CopyedFilesAmount / TimeElapsed, dove CopyedFilesAmount è la quantità di file già copiati. Il risultato però non è quello voluto, infatti la label "lbl_transfer_rate_amount" non mostra la velocità ma lo stesso identico valore di CopyedFilesAmount, quindi i file copiati. Dove sbaglio? Posto il codice del Form per maggiore chiarezza:
Codice:
Public Class frm_os_recovery

    Dim TimeElapsed As Integer = 1 'Tempo trascorso dall'inizio della copia



    '-----FUNIONE PER IL BACKUP DEI FILE------------------------------------------------------
    Private Sub Backup(ByVal sourceDir As String, ByVal targetDir As String)

        tmr_time_elapsed.Start()

        Dim files() As String = IO.Directory.GetFiles(sourceDir, "*.*", IO.SearchOption.AllDirectories)

        'Variabili per acquisizione dimensione cartella origine
        Dim FileSystemObject As Object = CreateObject("Scripting.Filesystemobject")
        Dim FolderCapture As Object = FileSystemObject.GetFolder(sourceDir)
        Dim DirectorySize As Integer

        'Variabili tempo
        Dim TransferRate As Integer 'Velocità di trasferimento
        Dim RemainingTime As Integer 'Tempo rimasto

        'Variabili per acquisizione dimensione file copiati
        Dim CopyedFilesAmount As Integer
        Dim CurrentFileSize As Integer

        'Impostazione proprietà "pbr_backup"
        With pbr_backup_progress
            .Minimum = 0
            .Value = .Minimum
            .Maximum = files.Count
        End With

        Dim newDir As String
        Dim FI As IO.FileInfo

        For Each f As String In files
            FI = New IO.FileInfo(f)
            newDir = targetDir & "\" & FI.DirectoryName.Substring(sourceDir.Length) & "\"
            If Not IO.Directory.Exists(newDir) Then IO.Directory.CreateDirectory(newDir)
            IO.File.Copy(f, newDir & FI.Name, True)

            '------------INCREMENTO PROGRESS BAR-----------------------------------
            pbr_backup_progress.Value += 1
            pbr_backup_progress.Update() 'Refresh

            '------------AGGIORNAMENTO VARIABILI-----------------------------------
            'Cartella

            DirectorySize = (FolderCapture.size / 1048576) 'Conversione Byte -> MB

            'Files
            CurrentFileSize = FI.Length 'Acquisizione dimensione file corrente
            CopyedFilesAmount += (CurrentFileSize / 1048576) 'Aggiornamento dimensione file copiati


            'Velocità di trasferimento
            TransferRate = CopyedFilesAmount / TimeElapsed

            'Tempo residuo
            If TransferRate > 0 Then
                RemainingTime = (DirectorySize - CopyedFilesAmount) / TransferRate
            End If


            '------------AGGIORNAMENTO ETICHETTE-----------------------------------
            'File copiati
            lbl_copyed_files_amount.Text = DirectorySize & "/" & CopyedFilesAmount & "MB"
            lbl_copyed_files_amount.Update() 'Refresh

            'Velocità di trasferimento
            lbl_transfer_rate_amount.Text = TransferRate & "MB/s"
            lbl_transfer_rate_amount.Update() 'Refres

            'Tempo residuo
            lbl_remaining_backup_time_amount.Text = RemainingTime & "s"
            lbl_remaining_backup_time_amount.Update()

        Next

        tmr_time_elapsed.Stop()
        lbl_copyed_files_amount.Text = DirectorySize & "/" & DirectorySize & "MB"
        pbx_backup_check.Visible = True

    End Sub
    '-------------------------------------------------------------------------------------------

    Private Sub cmd_demo_run_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmd_demo_run.Click
        Backup(sourceFolder, targetFolder)
    End Sub

    'Timer riportante il tempo trascorso
    Private Sub tmr_time_elapsed_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmr_time_elapsed.Tick
        TimeElapsed += 1 'Incremento tempo trascorso
    End Sub
   
End Class

Per il tempo residuo invece, come potete vedere dal codice ho già tentato di fare qualcosa ma non ho la minima idea se sia corretto fare così o meno, quindi se riuscite ad aiutarmi anche su questo mi fate un grosso favore.

Grazie in anticipo!! :)
 

coder7

Utente Attivo
951
295
CPU
Ryzen 3700X
Dissipatore
Thermalright
Scheda Madre
Asus B550-F Strix
HDD
Crucial MX300 525GB + Crucial M500 1 TB
RAM
16 GB DDR4 Corsair 3200
GPU
RX480 Nitro+ 4GB
Audio
Asus Xonar DGX
Monitor
Dell U2415
PSU
Seasonic Focus 550+ Gold
Case
Antec P280
OS
win10
Allora, ho provato un debugging al volo, tralasciando la Progress Bar:
La variabile "CopyedFilesAmount " va dichiarata assolutamente Double, tu infatti dividi per una costante (1048576)
e rischi di avere quindi la tua CopyedFilesAmount sempre a 0 quando il tuo file è inferiore al megabyte o 1 se è tra 1 e 2 mb etc,a meno che non sia semrpe un multiplo di quel valore in bytes...
Vb, infatti, da runtime efffettua una TRUNCATE matematica, che è semanticamente errata per questo tuo contesto.
Un'altra cosa che io farei, è evitare i metodi Update() sulle labels, creando un thread slegato dall'elaborazione, gestito poi con un RaiseEvent.
Ma è solo una sottigliezza.
 

money95

Nuovo Utente
17
0
Innanzitutto grazie di avermi risposto!
Poi, adesso ho fatto diventare double CopyedFilesAmount e per quanto riguarda il Timer l'ho sostituito con uno Stopwatch, che a quanto sembra non causa alcun problema e fa funzionare tutto correttamente. Per le labels adesso provo a farle aggiornare da un thread esterno, come mi avete consigliato.
Nel frattempo però mi sono reso conto di una cosa: la variabile "RemainingTime" contiene il tempo residuo in secondi, io però vorrei mostrare il tempo in ore, minuti e secondi nella forma "Tempo residuo: 00:00:00". C'è un modo semplice per farlo?
 

coder7

Utente Attivo
951
295
CPU
Ryzen 3700X
Dissipatore
Thermalright
Scheda Madre
Asus B550-F Strix
HDD
Crucial MX300 525GB + Crucial M500 1 TB
RAM
16 GB DDR4 Corsair 3200
GPU
RX480 Nitro+ 4GB
Audio
Asus Xonar DGX
Monitor
Dell U2415
PSU
Seasonic Focus 550+ Gold
Case
Antec P280
OS
win10
Direi di si, utilizzando lo String.Format( ) ;) (assumo che tu stia utilizzando VB con il framework .NET)
Googla un pò, vedrai che roba ;)
 

money95

Nuovo Utente
17
0
Il problema è che l'applicazione la sto attualmente sviluppando con Visual Basic 2013 Express, ma la versione "definitiva" dovrà essere per forza di cose scritta con VB6, visto che l'ambiente in cui andrò ad installare l'applicazione sarà sprovvisto di .NET Framework.
Esiste la controparte di String.Format( ) in VB6?
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!