Hi,
I'm trying to get some progress feedback from the following (Restore DB using SMO):

Sub DoRestore()
  Dim svr As Server = New Server("Server\SQL2008")
  Dim res As Restore = New Restore()
  res.Devices.AddDevice("C:\MyDB.bak", DeviceType.File)
  res.Database = "MyDB"
  res.RelocateFiles.Add(New RelocateFile("MyDB_Data", "C:\MyDB.mdf"))
  res.RelocateFiles.Add(New RelocateFile("MyDB_Log", "C:\MyDB.ldf"))
  res.PercentCompleteNotification = 1
  AddHandler res.PercentComplete, AddressOf ProgressEventHandler
  res.SqlRestoreAsync(svr)
End Sub

 Private Sub ProgressEventHandler(ByVal sender As Object, ByVal e As PercentCompleteEventArgs)
    ProgressBar.Value = e.Percent
  End Sub

This errors stating that the ProgressBar cannot be accessed from a thread it was not created on.

If I use res.SqlRestore it works but the UI is unresponsive.

I've tried to setup another event handler to pass the completion percentage back to the UI thread but not too sure what I'm doing here...

Private Sub ProgressEventHandler(ByVal sender As Object, ByVal e As PercentCompleteEventArgs)
        AddHandler e.Percent, AddressOf UpdateProgressBar
    End Sub

    Private Sub UpdateProgressBar(ByVal sender As Object, ByVal e As PercentCompleteEventArgs)
        ProgressBar.Value = e.Percent
    End Sub

I get "Percent is not an even of SMO.PercentCompleteEventArgs"

this may help. the issus is you need to set the progress bar value in directly through the useage of a delagate

i.e

       Sub DoRestore()
    Dim svr As Server = New Server("Server\SQL2008")
    Dim res As Restore = New Restore()
    res.Devices.AddDevice("C:\MyDB.bak", DeviceType.File)
    res.Database = "MyDB"
    res.RelocateFiles.Add(New RelocateFile("MyDB_Data", "C:\MyDB.mdf"))
    res.RelocateFiles.Add(New RelocateFile("MyDB_Log", "C:\MyDB.ldf"))
    res.PercentCompleteNotification = 1
    AddHandler res.PercentComplete, AddressOf ProgressEventHandler
    res.SqlRestoreAsync(svr)
    End Sub

    Private Sub ProgressEventHandler(ByVal sender As Object, ByVal e As PercentCompleteEventArgs)
      SetProgressBarValue_ThreadSafe(ProgressBar1, e.Percent)
    End Sub

'Create The Delegate
 Delegate Sub SetProgressBarValue_Delegate(ByVal [ProgressBar] As ProgressBar, ByVal [Value] As Integer)
    ' The delegates subroutine.
    Private Sub SetProgressBarValue_ThreadSafe(ByVal [ProgressBar] As ProgressBar, ByVal [Value] As Integer)
        ' InvokeRequired required compares the thread ID of the calling thread to the thread ID of the creating thread.
        ' If these threads are different, it returns true.
        If [ProgressBar].InvokeRequired Then
            Dim MyDelegate As New SetProgressBarValue_Delegate(AddressOf SetProgressBarValue_ThreadSafe)
            Me.Invoke(MyDelegate, New Object() {[ProgressBar], [Value]})
        Else
            [ProgressBar].Value = [Value]
        End If
    End Sub

Thanks for the feedback. I'd just like to point out that it's a good idea to check the dates on threads. This one is two years old and likely has been long since resolved or abandoned.

This article has been dead for over six months. Start a new discussion instead.