Backup scheduled with timer, Threads and Delegates VB.NET

3

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.

    
asked by Gonzalo 30.05.2016 в 22:46
source

2 answers

1

Maybe this can help you, since it complies with what you propose, if you are looking to save the data every so often (With a control Timer ) :

Imports System.Threading
Imports System.Threading.Tasks
Imports System.Windows.Forms

Partial Public Class Form1 Inherits Form

    Private Sub Form1_Load(Sender As Object, e As EventArgs) Handles MyBase.Load
        ' ... 
    End Sub

    Private Sub Timer_Backup_Tick(Sender As Object, e As EventArgs) Handles Timer_Backup.Tick
        Dim Thr As New Thread(new ThreadStart(AddressOf BackupManager.HacerBackup))
        Thr.Start()
        ' Esto crea otra entrada para el metodo RealizarBackup y la ejecuta.
    End Sub

End Class

Basically, just create another entry to make the code in the HacerBackup() method and then finish it.

The code may have to be fixed in the Visual Studio Error List (I'm not from VB.NET) , but the idea is readable, too, I recommend using a timer of System.Threading .

Finally, it is also not advisable to make backups while you are using the database on your system, so it would be better to run a backup when performing risky operations and when the program is finished.

    
answered by 31.05.2016 в 15:13
0

I recommend that you make the backup of the database in a separate program, it is more if possible in a service that starts with the system, the multi threading then, in c # the execution of the timer_eplapsed method is done in a separate thread, I do not know how it is in Visual Basic.net

here I leave a link to a book (is in English and oriented ac #, but given that the languages are very similar I imagine you can adapt it to VB.net) Developing Windows Services Succinctly in which you are shown how to develop services for windows (Also known as NT Services)

to create a new thread or thread you just have to use this code:

Dim thread as New Thread( Sub() HacerBackup() End Sub ) thread.Start()

    
answered by 30.05.2016 в 22:53