Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

How to populate DataGrid on background thread using Visual Basic 2005 .NET 2.0

Posted on 2007-11-22
3
Medium Priority
?
435 Views
Last Modified: 2013-11-07
I have been trying to show progress (progressbar) while populating a DataGrid on background thread using Visual Basic 2005 .NET 2.0.
There's always a glitch somewhere :(

Does anyone have a simple working example on how to do this ?

I do not understand how to use the methods for threads,
eg:
DoWork
ProgressChanged
RunWorkerCompleted

When I think I've worked it out I get this error:
code:  worker.ReportProgress(percentComplete)

This BackgroundWorker states that it doesn't report progress. Modify WorkerReportsProgress to state that it does report progress.



'I haven't supplied code because I've tried all sorts of ways and I've given up (code looks sloppy)
 
' here's an idea though:
' vb code:
start thread1
   fill datagrid on new thread
   var1 = "finished"  ' when done.
 
 
start thread2
show progressbar by loading new form.
do while var1 <> "finished"
  start timer.
  show progress from 0 to 100%
  end timer  ' do not sleep as this HALTS other threads as well.
 
  if var1 = finished then
     Exit Do
   end if
loop
 
   close progress form
   
 
 
  ....

Open in new window

0
Comment
Question by:siacom
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 16

Accepted Solution

by:
gnoon earned 2000 total points
ID: 20337691
Here for short principal:

There are two types of thread; UI thread and another thread

UI thread is a thread creates/updates thoses controls eg. buttons, forms, textboxes, etc.
Another thread is just a background/foreground thread does another job eg. connect db,

All threads will be arranged into CPU circularly for processing BUT only UI thread can update controls (call a property/method of a control, such as progressBar.Value = 100). Otherwise, you're in risk of deadlock or application frozen.

A function can be run in either UI thread and another thread, and the framework also provides a way to determine what type of current thread in a function.

If you have to do something with a control in a function, you have to check type of current thread before. If it is
- another thread, kicks it out of function and lets the next thread to be determined
- UI thread, allows it to update the control

The above is basic knowledge you need to know to deal with Windows Application and Thread, but not enought because you also need to know about delegate and event concept (related with thread), and also about filling datagrid.

However, the summarize is you procedure above seems doesn't work with thread. It should be this
' vb code:
start thread1
   start thread2 to fill datagrid and don't know when it will finish at here 
 
start thread2
show progressbar by loading new form (in another function on UI thread).
loop through all records in database reader
  add current record into datagrid (in another function on UI thread).
  update progress from 0 to 100% (current_rows / total_rows x 100) (in another function on UI thread).
loop until last record
close progress form (in another function on UI thread).

Open in new window

0
 

Author Comment

by:siacom
ID: 20347025
So I'm assumning that the UI thread is the BackgroundWorker in VB 2005 .NET is the UI method.
in which case
there are 4 methods:

DoWork
ProgressChanged
RunWorkerCompleted
Disposed

see code below.
on this section:
            If percentComplete > highestPercentageReached Then
                highestPercentageReached = percentComplete
                worker.ReportProgress(percentComplete)
            End If
I get this error:
This BackgroundWorker states that it doesn't report progress. Modify WorkerReportsProgress to state that it does report progress.

see complete form code below:

I am filling a datagrid and simply showing a progress bar until the datagrid is filled so if the progress reaches 100% it starts again.. this is fine for me as sometimes there are long delays connecting over the wan connection.




Imports System
Imports System.ComponentModel
Imports System.Threading
Imports System.Windows.Forms
 
 
Public Class THREAD
    Inherits Form
 
    Private highestPercentageReached As Integer = 0
 
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        ' Get the BackgroundWorker object that raised this event.
 
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        worker.ReportProgress(0, "Working..")
 
        worker.ReportProgress(100, "Complete!")
 
        e.Result = ProgressWorker(e.Argument, worker, e)
 
    End Sub
 
    Private Sub LoadingWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles LoadingWorker.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        e.Result = ProgressLoading(e.Argument, worker, e)
    End Sub
    Private Sub LoadingWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles LoadingWorker.ProgressChanged
        Loading.LoadProgress.Value = e.ProgressPercentage
    End Sub
    Private Sub LoadingWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles LoadingWorker.RunWorkerCompleted
        ' First, handle the case where an exception was thrown.
        If Not (e.Error Is Nothing) Then
            MessageBox.Show(e.Error.Message)
        ElseIf e.Cancelled Then
            MsgBox("Canceled")
        Else
            ' Finally, handle the case where the operation succeeded.
            MsgBox(e.Result.ToString())
        End If
 
    End Sub
 
    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        MsgBox("changed")
    End Sub
 
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        MsgBox("completed")
    End Sub
 
 
    Private Sub butEditCustomers_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butEditCustomers.Click
        Loading.Show()
        Application.DoEvents()
        LoadingWorker.RunWorkerAsync(35)
 
        '        EditCustomers.Show()
        '        Application.DoEvents()
        
        'BackgroundWorker1.RunWorkerAsync()
 
 
    End Sub
 
 
    Function ProgressWorker( _
        ByVal n As Integer, _
        ByVal worker As BackgroundWorker, _
        ByVal e As DoWorkEventArgs) As Long
 
        Dim result As Long = 0
 
        If worker.CancellationPending Then
            MsgBox("not filling")
            e.Cancel = True
        Else
            MsgBox("filling")
            Try
                Application.DoEvents()
                'TODO: This line of code loads data into the 'DsLocalities.Localities' table. You can move, or remove it, as needed.
                EditCustomers.LocalitiesTableAdapter.Fill(EditCustomers.DsLocalities.Localities)
                'TODO: This line of code loads data into the 'DsCustomers.Customers' table. You can move, or remove it, as needed.
                EditCustomers.CustomersTableAdapter.Fill(EditCustomers.DsCustomers.Customers)
                Application.DoEvents()
                EditCustomers.Refresh()
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
 
            e.Cancel = True
            '            LoadingWorker.CancelAsync()
 
        End If
 
        Return result
 
    End Function
 
    Function ProgressLoading( _
            ByVal n As Integer, _
            ByVal worker As BackgroundWorker, _
            ByVal e As DoWorkEventArgs) As Long
 
        Dim result As Long = 0
 
        If worker.CancellationPending Then
            e.Cancel = True
            Loading.Close()
            MsgBox("canceled")
        Else
            If n < 2 Then
                result = 1
            Else
                result = ProgressLoading(n - 1, worker, e) + _
                         ProgressLoading(n - 2, worker, e)
            End If
 
            ' Report progress as a percentage of the total task.
            Dim percentComplete As Integer = CSng(n) / CSng(CInt(35)) * 100
 
 
            If percentComplete > highestPercentageReached Then
                highestPercentageReached = percentComplete
                worker.ReportProgress(percentComplete)
            End If
 
        End If
 
        Return result
 
 
 
 
    End Function
 
 
 
    Private Sub THREAD_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
    End Sub
 
End Class

Open in new window

0
 
LVL 16

Expert Comment

by:gnoon
ID: 20348479
Can you post BackgroundWorker class?
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

664 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question