Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle events in another class

I'm trying to move some code into some class files to clean up my code. One area I'm having trouble with is reporting progress for events between the object performing the task and a progress bar.

I guess the event functions have to be placed in the new class but they also need to update the progress bar on the calling form? Can the class\object return updates in place of the event handlers?

Currently the form has all the code:

Function DoRestore(ByVal SQLServer As String, ByVal BackupFilePath As String, ByVal DatabaseName As String)
    Dim Server As Server = New Server(SQLServer)
    Server.ConnectionContext.ApplicationName = Application.ProductName
    Dim res As Restore = New Restore()
    Dim dt As DataTable

        res.Devices.AddDevice(BackupFilePath, DeviceType.File)
        dt = res.ReadFileList(Server)
        res.Database = DatabaseName
        res.PercentCompleteNotification = 1
        AddHandler res.PercentComplete, AddressOf RestoreProgressEventHandler
        AddHandler res.Complete, AddressOf RestoreCompleteEventHandler

        res.SqlRestoreAsync(Server)
        While res.AsyncStatus.ExecutionStatus = ExecutionStatus.InProgress
            Application.DoEvents()
        End While

End Function



Private Function RestoreProgressEventHandler(ByVal sender As Object, ByVal e As PercentCompleteEventArgs)
 'Update progress bar (e.Percent)
End Function



Private Sub RestoreCompleteEventHandler(ByVal sender As Object, ByVal e As Microsoft.SqlServer.Management.Common.ServerMessageEventArgs)
'Signal completion
End Sub

Used via:

DoRestore(SQLServer, "C:\SQLBACKUP.bak", DatabaseName)
like image 222
madlan Avatar asked Dec 17 '22 09:12

madlan


2 Answers

You should be defining an event in your class and handling the progress bar update in the form (assuming WinForms?) - the point here is that the class is concerned with backing up something - it shouldn't have any concept of progress bars:

Define the event in the class:

Public Event ReportProgress(byval progress as integer)

Raise this event as required when doing the backup:

RaiseEvent ReportProgress(value)

In the calling code you either need to

  • Define a class using WithEvents:

    Private WithEvents Backup As BackupClass
    

    and then act on the event:

    Private Sub Backup _ReportProgress(progress As Integer) Handles Backup.ReportProgress
        Debug.WriteLine("Progress:" + progress.ToString)
    End Sub
    
  • Or add a handler manually:

    Private Sub Backup_ReportProgressHandler(progress As Integer)
        Debug.WriteLine("Progress Handler:" + progress.ToString)
    End Sub
    
    AddHandler Backup.ReportProgress, AddressOf Backup_ReportProgressHandler
    
like image 193
Matt Wilko Avatar answered Jan 05 '23 23:01

Matt Wilko


Well you can do this, but to be honest I find it less confusing if things like event handlers that update a progress bar for a form are in that form. Otherwise to maintain it later (to fix a progress bar issue for example), I now need to go on an expedition to figure out where you hid it.

So IMO, if a form calls a class that does something, and that class is returning progress notifications, it's a good idea to handle those notifications in the calling form.

like image 23
Tridus Avatar answered Jan 05 '23 22:01

Tridus