I have a system on vb.net which has the function HacerBackup()
that is activated with a button and saves a backup of the database on a removable device.
Then the client asked me to make automatically certain days every certain time and then the problem arose with these thread issues.
The following code is found in the event Form.Load
, after some IF (If the scheduled backup is activated, what days it will do and how often)
Dim tiempo As Integer = (CInt(TablaConfiguracion.Rows(10)(1)) * 60000) 'Intervalo en minutos
Timer_Backup.Interval = tiempo
Timer_Backup.Enabled = True
Then in the Timer_Backup_Tick I call the function HagaBackup ()
Private Sub Timer_Backup_Tick(sender As Object, e As EventArgs) Handles Timer_Backup.Tick
HacerBackup()
End Sub
But the problem is that when you perform the backup (which takes time) the program stops until it ends. I need to create another background thread to do the data compression and copy while the user is still working.
As I have no idea about Multi-Threading and what I found was unintelligible, I consulted them about methods or how they can be done.
EDITED:
I solved it using "AddHandler Timer_Backup.Elapsed, AddressOf Timer_Tick" as seen below:
'-----------------------------------------------------------------------------------'
'Si esta activado el BACKUP PROGRAMADO llama a la funcion HacerBackup cada X minutos'
'-----------------------------------------------------------------------------------'
If TablaConfiguracion.Rows(9)(1) = True Then
Dim dias As String() = TablaConfiguracion.Rows(11)(1).Split(",")
Dim hoy As String = Today.DayOfWeek
'Si esta tildado el dia en preferencias'
If dias(hoy - 1) = "1" Then
Dim tiempo As Integer = (CInt(TablaConfiguracion.Rows(10)(1)) * 60000) 'Intervalo en minutos'
'Aquí creo el timer y le agrego como Handler.Elapsed la dirección de memoria del subproceso Timer_Tick'
Timer_Backup = New System.Timers.Timer()
AddHandler Timer_Backup.Elapsed, AddressOf Timer_Tick
Timer_Backup.Interval = tiempo
Timer_Backup.Enabled = True
End If
End If
But I have a new question, I have a label in the Form_Principal which I want to show the date and time of the last backup
Shared Sub Timer_Tick(source As Object, e As System.Timers.ElapsedEventArgs)
If HacerBackup() = True Then
Dim ultimo_backup As String = e.SignalTime.ToString("dd/MM/yyyy - HH:mm")
Form_Principal.Label_Principal_UltimoBK.Text = ultimo_backup
End If
End Sub
But when executing the instruction the label is not changed. And if I put it as private it returns the following:
Invalid operation through subprocesses: Control was accessed 'Label_Principal_UltimoBK' from a subprocess other than that in which He created it.
LAST EDIT: (And Definitive Solution)
I solved it using delegates, as I show below:
Delegated function:
Delegate Sub DelegadoCambiarLabel(ByVal texto As String)
Function that changes the label:
Private Sub CambiarLabelBackup(ByVal texto As String)
Me.Label_Principal_UltimoBK.Text = texto
End Sub
Adding to the Call function in each Tick of the timer:
Private Sub Timer_Tick(source As Object, e As System.Timers.ElapsedEventArgs)
If HacerBackup() = True Then
Dim ultimo_backup As String = e.SignalTime.ToString("dd/MM/yyyy - HH:mm")
'Creamos una instancia del delegado, llamando a la función CambiarLabelBackup'
Dim Delegado As New DelegadoCambiarLabel(AddressOf CambiarLabelBackup)
'Invocamos esa instancia y le pasamos como objeto el string en cuestión'
Me.Invoke(Delegado, New Object() {ultimo_backup})
TablaConfiguracion(12)(1) = ultimo_backup
EscribeINI()
End If
End Sub
And voila! All done. Thanks.