Need help while working with timer....

I am trying to do the database restoring part....

When the user clicks on the restore database button the progress bar shud be shown and as soon as the restoring is completed the progress bar shud stop and display success msg...

Right now I tried without timer using progress image but it is not working as expected...
the image shows just when the success msg is displayed....

below is my code

Imports Microsoft.Win32
Imports Microsoft.SqlServer.Management.Smo
Imports System.Data.SqlClient
Imports System.IO

Public Class frmDatabaseRestore

     Private Sub frmDatabaseRestore_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

          lblAlert.Visible = False
          lblAlert.Image = My.Resources.Loading1 'my processing image

          txtDatabase.Text = "Databasename"
          cboServer.Text = "Servername"
     End Sub

     Private Sub btnClose_Click(sender As System.Object, e As System.EventArgs) Handles btnClose.Click
          If MessageBox.Show("Restoring Database Aborted, your system will shutdown", "Restore Database Aborted", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) = Windows.Forms.DialogResult.Yes Then
               Application.Exit()
          End If
     End Sub

     Private Sub btnRestore_Click(sender As System.Object, e As System.EventArgs) Handles btnRestore.Click
          If optBackupFile.Checked = False And optTextFile.Checked = False Then
               MessageBox.Show("Select any one option")
          ElseIf optBackupFile.Checked = True Then
               If cboServer.Text = "" Or cboServer.Text = "Select" Then
                    MessageBox.Show("Server Name is Mandatory")
               Else
                    lblAlert.Visible = True 'display the processing image
                    Try
                         Dim MySQL_Connection As SqlConnection = New SqlConnection()
                         MySQL_Connection.ConnectionString = "Data Source = " & cboServer.Text & ";Integrated Security  = True"
                         MySQL_Connection.Open()
                         Dim myCommand As SqlCommand
                         myCommand = New SqlCommand(" RESTORE DATABASE [Databasename] FROM  DISK = N'D:\Databasename_full.bak'", MySQL_Connection)
                         myCommand.ExecuteNonQuery()
                         MySQL_Connection.Close()
                         lblAlert.Visible = False
                         MessageBox.Show("Database Restored Successfully")
                         frmUserLogin.Show()
                         Me.Close()
                    Catch ex As Exception
                         WriteLog(New StackTrace(New StackFrame(True)).GetFrame(0).GetFileLineNumber, ex.Message & "Restore Database Fail")
                         MessageBox.Show("Restore Database Fail")
                    End Try
               End If
               'else retore database based on text files
          ElseIf optTextFile.Checked = True Then
               If cboServer.Text = "" Or cboServer.Text = "Select" Then
                    MessageBox.Show("Server Name is Mandatory")
               Else
                    lblAlert.Visible = True
                    Dim MySQL_Connection As SqlConnection = New SqlConnection()
                    MySQL_Connection.ConnectionString = "Data Source = " & cboServer.Text & ";Integrated Security  = True"
                    MySQL_Connection.Open()
                    Dim myCommand As SqlCommand
                    Dim dbstatus As Boolean

                    'Creating Database
                    myCommand = New SqlCommand("CREATE DATABASE Databasename", MySQL_Connection)
                    myCommand.ExecuteNonQuery()

                    MySQL_Connection.Close()

                    Dim myconn As SqlConnection = New SqlConnection
                    dbstatus = Open_DB_Connection(myconn)
                    'Creating Tables
                    myCommand = New SqlCommand("CREATE TABLE Table1 (Col1 int NULL,Col2 int NULL)", myconn)
                    myCommand.ExecuteNonQuery()

                    myCommand = New SqlCommand("CREATE TABLE Table2 (Colname1 varchar(1) NOT NULL,Colname2 varchar(25))", myconn)
                    myCommand.ExecuteNonQuery()

                    Dim FileName As String
                    Dim i As Integer = 0
                    Dim Names_Of_Tables() As String

                    Dim dbCmd As SqlCommand = New SqlCommand()

                    Names_Of_Tables = {"Table1", "Table2"}

                    For i = 0 To Names_Of_Tables.Length - 1
                         FileName = "D:\" & Names_Of_Tables(i) & ".txt"
                         If File.Exists(FileName) Then
                              Debug.Print("Filename: " + FileName)
                              Debug.Print("Names_Of_Tables: " + Names_Of_Tables(i))
                              Try
                                   dbCmd = New SqlCommand("BULK INSERT " & Names_Of_Tables(i) & " FROM '" & FileName & "' WITH (FIELDTERMINATOR = '^', ROWTERMINATOR = '\n');", myconn)
                                   Debug.Print("Query: " + dbCmd.CommandText)
                                   dbCmd.ExecuteNonQuery()
                                   MessageBox.Show(Names_Of_Tables(i) & " - Table created successfully")
                              Catch ex As Exception
                                   MessageBox.Show(ex.Message)
                              End Try
                         Else
                              MessageBox.Show("File " + FileName + " does not exists")
                         End If
                    Next

                    '**************************************************************** 
                    dbstatus = Close_DB_Connection(myconn)
                    lblAlert.Visible = False
                    MessageBox.Show("Database Restored Successfully")
                    frmUserLogin.Show()
                    Me.Close()
               End If
          End If
     End Sub

End Class

Recommended Answers

All 14 Replies

If I am not wrong, you are using the same thread to show the progress bar and run the restore. That's why this isn't working out so well, as the thread is busy with SQL and doesn't get to process your progress bar until it's finished.

My suggestion is to use a backgroundworker for the SQL part of your code and use the normal thread for the rest (progress bar). When you start the worker you show the progress bar and when the worker ends you hide the progress bar.

Have a look here http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx and here http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

I don't know how you are going to manage a progress bar because the RESTORE command, even if running in a background thread, will not report back the progress of the operation. It will just halt the execution of the thread until it completes. The best you'll do is display 0% at the start, then 100% at the end.

I tried to work with the below tutorial but I am not aware as to how to use the delegate for my radio button and combo box....

Click Here

I get the following error

Cross-thread operation not valid: Control 'cboServer' accessed from a thread other than the thread it was created on.

Need help to work on delegate

Post your code so I can see how you are handling the delegate. As an example, let's assume I have a background thread that is scanning a directory tree. Every time it finds a new file I want to add that file name to a textbox control. At the class level I declare a delegate as

Private Delegate Sub AppendFileDelegate(ByVal text As String)

If you were just doing the file scan without using a background thread you could get away with

Private Sub AppendFile(ByVal text As String)
    txtFiles.AppendText(text & vbCrLf)
End Sub

but because the background thread does not have direct access to txtFiles you have to use the delegate as

Private Sub AppendFile(ByVal text As String)

    If txtFiles.InvokeRequired Then
        Dim myDelegate As New AppendFileDelegate(AddressOf AppendFile)
        Me.Invoke(myDelegate, text)
    Else
        txtFiles.AppendText(text & vbCrLf)
    End If

End Sub

But I will reiterate, I don't see how you are going to implement a useful progress bar on an operation that does not require a loop. I could see it if you were doing something like copying files. Let's say you had to copy 100 files. You could do

bgw.ReportProgress(0)

For i = 1 to 100
    'copy the next file
    bgw.ReportProgress(i)
Next

This would fire the ReportProgress event after each copy. However if you were just copying one massive file then

bgw.ReportProgress(0)
'copy the massive file
bgw.ReportProgress(100)

would get you nothing except a progress bar that shows either 0 or 100. There's no way it can show you the progress of the actual copy. That's effectively what you are doing by executing the RESTORE sql command.

You can use a background worker for the restore part and a timer for the progress bar and get an effect like when loading windows (where the bar fills up, empties and then fills up again).

But that won't give you a true progress bar. It just gives you something to look at without any indication of when it will complete. Come to think of it, that is a progress bar - at least how Microsoft implements it. ;-P

For me progress bars serve 1 purpose: Notify the user that the operation is still running (and also don't end task and screw everything up).
This purpose is served just fine with a nice animation, or a progress bar that fills and empties or even with a background worker that will allow your apps window to move freely and won't give the user the feeling that it has frozen.

The solution you propose shows neither progress nor status. If the RESTORE gets hung up for any reason, the Timer will continue to update the display (I refuse to call this a progress bar since it does not show progress) leaving the user with the mistaken belief that the process is actually running.

I wont use progress bar but just and loading gif image...
My issue is where I have written cboServer.Text="" or cboServer.Text="Select"...I am getting error at this place...so I dont know what delegat shud be used in this case....
Error is - Cross-thread operation not valid: Control 'cboServer' accessed from a thread other than the thread it was created on.

It shouldn't be that hard.
Move the whole code you've got for the btnRestore_Click sub into the backgroundworker.dowork. Remove all references to progress bars/animations or whatever from the dowork sub.
On btnRestore.Click call backgroundworker.runworkerasync and display your animation.
on the boackgroundworker.runworkercompleted sub hide your animation.

Post back your code if you still have problems.

Public Class Form1

    Private Delegate Sub UpdateServerDelegate(ByVal text As String)
    .
    .
    .        
    Private Sub UpdateServer(ByVal text As String)

        If cboServer.InvokeRequired Then
            Dim myDelegate As New UpdateServerDelegate(Address Of UpdateServer)
            Me.Invoke(myDelegate, text)
        Else
            cboServer.Text = text
        End If

    End Sub

and in your background thread you do

UpdateServer("some text")

and the UpdateServer Sub will handle calling the delegate if needed.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.