locked
Updating Progress While Filling Dataset RRS feed

  • Question

  •  

    I am filling a dataset incrementally and updating the progress for a progressbar, but the progress bar is not incrementing at all. I am passing the value ByRef and i have verified that the value is increasing appropriately, yet the progressbar is not moving.

     

    Here is my method to fill the dataset:

     

     

    Code Block

    Public Function RetrieveDataSet(ByVal qry As String, _

    ByVal count_qry As String, _

    ByRef progress As Integer) As DataSet

     

    Dim ds As New DataSet

    Dim cn As New SqlConnection(ConnectString)

    Dim intRecords As Integer = 0

     

    Try

    Dim cmd As New SqlCommand(count_qry, cn)

    Dim da As New SqlDataAdapter(qry, cn)

    cn.Open()

    intRecords = CInt(cmd.ExecuteScalar)

    For i As Integer = 0 To intRecords Step 100

     

    da.Fill(ds, i, 100, "Customers")

    progress = i

    Next

     

    Catch ex As SqlException

    Throw New Exception("There was a problem connecting to the database.")

    Catch ex As Exception

    Throw ex

    Finally

    cn.Close()

    End Try

     

    Return ds

    End Function

     

     

    I am calling the data as so:

     

    Code Block

    sForm.ProgressBar1.Maximum = CustomerDatalayer.GetTotalCustomers()

    CustomerDS = CustomerDatalayer.GetCustomers(sForm.ProgressBar1.Value)

     

    ' From the datalayer...

    Public Function GetCustomers(ByRef progress As Integer) As DataSet

    Return d.RetrieveDataSet("SELECT * FROM vw_CustomersParent ORDER BY Cst_Name", _

    "SELECT COUNT(*) FROM vw_CustomersParent", progress)

    End Function

     

    Public Function GetTotalCustomers() As Integer

    Return CType(d.GetValue("SELECT COUNT(*) FROM vw_CustomersParent"), Integer)

    End Function

     

     

    I should also note that the progressbar is on a splash form and the code is executed from the "main" form.
    Monday, October 1, 2007 12:00 PM

Answers

  • Hi, jrsearles,

     

    Based on my understanding, you want to show the loading progress in your Splash Form, don't you?

     

    In fact, the Splash Form is not in the Main Thread of your application, so you should call some delegates to show the progress.

    I wrote a small sample which may help you to solve this problem.

    1) Add a new SplashScreenMainFormLoadingClass.vb

       This class is used to handle the messages sent from your main form.

    Code Block

    Public Delegate Sub SplashScreenMainFormLoadingItemHandler(ByVal sender As Object, ByVal progress As Integer)

     

    Public Class SplashScreenMainFormLoadingClass

        Protected Friend Shared Event SplshScreenFormEvent As SplashScreenMainFormLoadingItemHandler

        Private IsFirst As Boolean = False

        Public Sub SendItemMessage(ByVal sender As Object, ByVal progress As Integer)

            System.Threading.Thread.Sleep(0)

            If Not IsFirst Then

                RaiseEvent SplshScreenFormEvent(Nothing, Nothing)

                IsFirst = True

            End If

            RaiseEvent SplshScreenFormEvent(sender, progress)

        End Sub

    End Class

     

     

    2) in the Splash Form

        We can set the value through some delegate.

    Code Block

        Private Delegate Sub SetTextCallback(ByVal progress As Integer)

        Private WithEvents MainFormLoadingClass As New SplashScreenMainFormLoadingClass

     

        Private Sub OnLoadingItemChanged(ByVal sender As Object, ByVal progress As Integer) Handles MainFormLoadingClass.SplshScreenFormEvent

            If Me.ProgressBar1.InvokeRequired Then

                Dim d As New SetTextCallback(AddressOf SetProgress)

                Me.Invoke(d, New Object() {progress})

            Else

                SetProgress(progress)

            End If

        End Sub

     

        Private Sub SetProgress(ByVal progress As Integer)

            Me.ProgressBar1.Value = progress

        End Sub

     

     

    3) in the Main Form

        We send the value to the SplashScreenMainFormLoadingClass.

    Code Block

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

            Dim SendMessage As New SplashScreenMainFormLoadingClass

            Dim MaxValue = 2000

            Dim StepValue = 100

            For i As Integer = 0 To MaxValue Step StepValue

                SendMessage.SendItemMessage(Nothing, i / (MaxValue / StepValue))

                System.Threading.Thread.Sleep(500)

            Next 

        End Sub

     

     

    Hope this helps,

    Regards

    Thursday, October 4, 2007 2:34 AM

All replies

  • Hi, jrsearles,

     

    Based on my understanding, you want to show the loading progress in your Splash Form, don't you?

     

    In fact, the Splash Form is not in the Main Thread of your application, so you should call some delegates to show the progress.

    I wrote a small sample which may help you to solve this problem.

    1) Add a new SplashScreenMainFormLoadingClass.vb

       This class is used to handle the messages sent from your main form.

    Code Block

    Public Delegate Sub SplashScreenMainFormLoadingItemHandler(ByVal sender As Object, ByVal progress As Integer)

     

    Public Class SplashScreenMainFormLoadingClass

        Protected Friend Shared Event SplshScreenFormEvent As SplashScreenMainFormLoadingItemHandler

        Private IsFirst As Boolean = False

        Public Sub SendItemMessage(ByVal sender As Object, ByVal progress As Integer)

            System.Threading.Thread.Sleep(0)

            If Not IsFirst Then

                RaiseEvent SplshScreenFormEvent(Nothing, Nothing)

                IsFirst = True

            End If

            RaiseEvent SplshScreenFormEvent(sender, progress)

        End Sub

    End Class

     

     

    2) in the Splash Form

        We can set the value through some delegate.

    Code Block

        Private Delegate Sub SetTextCallback(ByVal progress As Integer)

        Private WithEvents MainFormLoadingClass As New SplashScreenMainFormLoadingClass

     

        Private Sub OnLoadingItemChanged(ByVal sender As Object, ByVal progress As Integer) Handles MainFormLoadingClass.SplshScreenFormEvent

            If Me.ProgressBar1.InvokeRequired Then

                Dim d As New SetTextCallback(AddressOf SetProgress)

                Me.Invoke(d, New Object() {progress})

            Else

                SetProgress(progress)

            End If

        End Sub

     

        Private Sub SetProgress(ByVal progress As Integer)

            Me.ProgressBar1.Value = progress

        End Sub

     

     

    3) in the Main Form

        We send the value to the SplashScreenMainFormLoadingClass.

    Code Block

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

            Dim SendMessage As New SplashScreenMainFormLoadingClass

            Dim MaxValue = 2000

            Dim StepValue = 100

            For i As Integer = 0 To MaxValue Step StepValue

                SendMessage.SendItemMessage(Nothing, i / (MaxValue / StepValue))

                System.Threading.Thread.Sleep(500)

            Next 

        End Sub

     

     

    Hope this helps,

    Regards

    Thursday, October 4, 2007 2:34 AM
  • Thanks a lot! I have a lot to learn with threading, delegates, etc.

     

    I have it working, but it's a bit clunky right now. My data handling is in a separate project and i'm having a problem figuring out the best way to pass the progress back to the main app. Right now i am passing a backgroundworker object to the data layer and having the datalayer reportprogress back to my app.

     

    What i'm thinking about doing is setting up a readonly property of my datalayer which will hold the progress and then poll that property from the main application.

     

    Josh

     

    Thursday, October 4, 2007 10:21 PM