Solved

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

Posted on 2007-11-22
3
432 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
  • 2
3 Comments
 
LVL 16

Accepted Solution

by:
gnoon earned 500 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

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
how to just get time from a date 6 34
Input parameteres to DragOver 2 20
PowerShell:  Column widths won't expand 3 21
IDE for Python 5 26
This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

828 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