[2005] BackgroundWorker and Progress Bar
Hi! I tried running this backgroundworker of jm which is perfectly running.
vb Code:
Public Class frmBackGroundWorker
Private Sub frmBackGroundWorker_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Raise the DoWork event in a worker thread.
Me.BackgroundWorker1.RunWorkerAsync()
End Sub
'This method is executed in a worker thread.
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
For i As Integer = 1 To 100
'Raise the ProgressChanged event in the UI thread.
worker.ReportProgress(i, i & " iterations complete")
'Perform some time-consuming operation here.
Threading.Thread.Sleep(250)
Next i
End Sub
'This method is executed in the UI thread.
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Me.ProgressBar1.Value = e.ProgressPercentage
Me.Label1.Text = TryCast(e.UserState, String)
End Sub
'This method is executed in the UI thread.
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Me.Label1.Text = "Operation complete"
End Sub
End Class
the project i am working will access a database table that will take some time to load and I would like that while it is being fetch, users will see a progress of the loading process. How do i make backgroundworker use the data amount of data as value of the progressbar?
Right now, I click a button to fetch the records from a database table. Below is my code
Code:
Private Sub btnDisplay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisplay.Click
SuspendLayout()
cnn.ConnectionString = "Data Source=.\sqlexpress;Initial Catalog=MyDatabase;Integrated Security=True"
If cnn.State = ConnectionState.Closed Then cnn.Open()
cmdGrade = cnn.CreateCommand
cmdGrade.CommandText = "SELECT DISTINCT * FROM tblEnrol WHERE SectionName = '" & cboSection.Text & "' AND SubjectName = '" & cboSubjectName.Text & "' AND YearLevel = '" & cboYearLevel.Text & "'"
daGrade.MissingSchemaAction = MissingSchemaAction.AddWithKey
dsGrade.Clear()
'dsSection.Clear()
'dsSubject.Clear()
daGrade.SelectCommand = cmdGrade
daGrade.Fill(dsGrade, "tblEnrol")
cnn.Close()
Dim si() As FarPoint.Win.Spread.SortInfo = New FarPoint.Win.Spread.SortInfo() {New FarPoint.Win.Spread.SortInfo(1, True), New FarPoint.Win.Spread.SortInfo(2, True)}
''HideSheets()
'bind fpspread1 to datasource
'1st Grading
FpSpread1.Sheets(0).DataSource = dsGrade
FpSpread1.Sheets(0).DataMember = "tblEnrol"
'Create CellType and specify number decimal for 1st grading sheet
With FpSpread1.Sheets(0)
.DataAutoCellTypes = False
Dim num As New FarPoint.Win.Spread.CellType.NumberCellType
num.DecimalPlaces = 0
.Columns(12, 81).CellType = num 'column 12 to 81
.Columns(84, 85).CellType = num
.Columns(88, 89).CellType = num
.Columns(92, 93).CellType = num
.Columns(96, 97).CellType = num
.Columns(100, 101).CellType = num
.Columns(104, 105).CellType = num
.Columns(109).CellType = num
'sort multi-column
.SortRows(0, FpSpread1.Sheets(0).RowCount, si)
End With
FormatSpread()
'bind FpSpread1.Sheets(1) to datasource
'2nd Grading
FpSpread1.Sheets(1).DataSource = dsGrade
FpSpread1.Sheets(1).DataMember = "tblEnrol"
'Create CellType and specify number decimal for 1st grading sheet
With FpSpread1.Sheets(1)
.DataAutoCellTypes = False
Dim num As New FarPoint.Win.Spread.CellType.NumberCellType
num.DecimalPlaces = 0
'for 2nd grading cell type
.Columns(135, 204).CellType = num 'Assignment to Total Score (A)
.Columns(207, 208).CellType = num 'Total Quiz to Total Score (Q)
.Columns(211, 212).CellType = num 'Total Rec to Total Score (R)
.Columns(215, 216).CellType = num 'Total Proj to Total Score (P)
.Columns(219, 220).CellType = num 'Total Speech to Total Score (SP)
.Columns(223, 224).CellType = num 'Total Reading to Total Score (RDG)
.Columns(227, 228).CellType = num 'Total Exam to Total Score (E)
.Columns(232).CellType = num 'Average
End With
FormatSpread1()
ResumeLayout()
End Sub
Re: [2005] BackgroundWorker and Progress Bar
You can't. You're executing synchronous operations in that method so where exactly would you report the progress? You could report progress between each distinct task but if you wanted to indicate how far through processing the data you were you'd have to be processing the records sequencially, which you're not.
Re: [2005] BackgroundWorker and Progress Bar
I just wanted the user to see that something is going on while the apps is fetching data from the sql server, like a progress bar to let user to wait.
1 Attachment(s)
Re: [2005] BackgroundWorker and Progress Bar
I saw this code somewhere I can't remember it anymore. I call the form where I put the code whenever the user click the display button but the the problem is I can't see any text or progress bar displaying. it is somewhat suspended. The attached pic shows how it looks like. Sometimes I can see the progress bar but not moving. I also noticed that when I run the form and click display, there's no error at all but for the second time around I will close the form and click display button again i get this error Thread is running or terminated; it cannot restart.
vb Code:
Public Class frmloader
Private Thread1 As New Threading.Thread(AddressOf GrabData)
Private Sub GrabData()
'********************************
'MY COMPLEX DATA GATHERING THREAD, CAN
'TAKE AS MUCH AS 1 MINUTE TO COMPLETE
'*********************************
Me.Invoke(New MethodInvoker(AddressOf ThreadFinished))
End Sub
Private Sub frmLoader_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
Thread1.Start()
'*****************************************
'RIGHT HERE I WANT TO WAIT FOR THREAD1 TO BE DONE,
'WITHOUT SLEEPING, OR STOPPING THE MAIN THREAD.
'*************************************
End Sub
Private Sub ThreadFinished()
'frmMain.Show()
Me.Close()
End Sub
End Class
Re: [2005] BackgroundWorker and Progress Bar
If you just want to indicate that something is happening then just set the ProgressBar's Style to Marquee.
As for your last post, the comments in the Shown event handler don't make any sense. How can the main thread wait for the other thread to complete and yet not be sleeping or stopped? If it isn't sleeping or stopped then it's not waiting. It's executing. I would suggest that you go back to using a BackgroundWorker. You just call RunWorkerAsync and let it go. It will then notify you when it's finished its work by raising its RunWorkerCompleted event. If you haven't read my BackgroundWorker example in the CodeBank I suggest that you do so.
Re: [2005] BackgroundWorker and Progress Bar
to Simply Me
so because you have the thread start in the form_shown procedure, with the picture you provided... it allowed the form to redraw itself during the complex events?
Re: [2005] BackgroundWorker and Progress Bar
Quote:
Originally Posted by jmcilhinney
If you just want to indicate that something is happening then just set the ProgressBar's Style to Marquee.
As for your last post, the comments in the Shown event handler don't make any sense. How can the main thread wait for the other thread to complete and yet not be sleeping or stopped? If it isn't sleeping or stopped then it's not waiting. It's executing. I would suggest that you go back to using a BackgroundWorker. You just call RunWorkerAsync and let it go. It will then notify you when it's finished its work by raising its RunWorkerCompleted event. If you haven't read my BackgroundWorker example in the CodeBank I suggest that you do so.
jm, the code in my first post is your code.
Re: [2005] BackgroundWorker and Progress Bar
Quote:
Originally Posted by Simply Me
jm, the codd in my first post is your code.
Well then, you know how to use the RunWorkerCompleted event.
Re: [2005] BackgroundWorker and Progress Bar
i don't have idea on how to make use of it. i just tried it and i want to use it in my proj but i need it to process the amount of data the proj is fetching as the value of the progress bar.
Re: [2005] BackgroundWorker and Progress Bar
You seem to be under the impression that the BackgroundWorker can perform some sort of magic. It cannot. All it can do for you is pass a value from the background thread to the UI thread. That's all. It's up to YOU to calculate that value in the first place and then to use it in the UI thread. Telling us that you want to report progress is no use if you can't actually calculate that progress in the first place, which you can't.
Re: [2005] BackgroundWorker and Progress Bar
with that, what's the best way to just display the something is going while the user awaits for the completion of a loading process?
Re: [2005] BackgroundWorker and Progress Bar
Quote:
Originally Posted by Simply Me
with that, what's the best way to just display the something is going while the user awaits for the completion of a loading process?
I already answered that very question in post #5.
Re: [2005] BackgroundWorker and Progress Bar
this is what I have
Code:
Private Sub frmBackGroundWorker_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Raise the DoWork event in a worker thread.
''Me.BackgroundWorker1.RunWorkerAsync()
End Sub
'This method is executed in a worker thread.
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
'For i As Integer = 1 To 100
' 'Raise the ProgressChanged event in the UI thread.
' worker.ReportProgress(i, i & " iterations complete")
' 'Perform some time-consuming operation here.
' Threading.Thread.Sleep(250)
'Next i
Me.BackgroundWorker1.RunWorkerAsync()
End Sub
'This method is executed in the UI thread.
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Me.ProgressBar1.Value = e.ProgressPercentage
Me.Label1.Text = TryCast(e.UserState, String)
End Sub
'This method is executed in the UI thread.
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Me.Label1.Text = "Operation complete"
End Sub
End Class
I call this form whenever I click display button but its just displaying the form and not fetching the records from the database its only when I close the form that it displays the records.
Re: [2005] BackgroundWorker and Progress Bar
Um, you're calling RunWorkerAsync in the DoWork event handler. The DoWork event is raised WHEN you call RunWorkerAsync. In your case you're trying to start the BackgroundWorker after it's started. That's not going to work.
It's very simple:
1. When the form is displayed call RunWorkerAsync.
2. In the DoWork event handler retrieve your data.
3. In the RunWorkerCompleted event handler close the form.
When the form is closed the caller can then retrieve the data from a property and display it.
Re: [2005] BackgroundWorker and Progress Bar
On this form, add a ProgressBar and set its Style to Marquee. This is all the code you need:
vb.net Code:
Private _data As New DataTable
Public ReadOnly Property Data() As DataTable
Get
Return Me._data
End Get
End Property
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles MyBase.Load
Me.BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, _
ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Using connection As New SqlConnection("connection string here")
Using command As New SqlCommand("SQL query here", connection)
connection.Open()
Using reader As SqlDataReader = command.ExecuteReader(CommandBehavior.KeyInfo)
Me._data.Load(reader)
End Using
End Using
End Using
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Me.DialogResult = Windows.Forms.DialogResult.OK
End Sub
In the caller the code would look something like this:
vb.net Code:
Using dialogue As New ProgressForm
If dialogue.ShowDialog() = Windows.Forms.DialogResult.OK Then
Dim table As DataTable = dialogue.Data
'Use table here.
End If
End Using
Re: [2005] BackgroundWorker and Progress Bar
here is my code form where I will call the form frmback. It has already the connectionstring. Whenever I click the display button records will be displayed according to what is selected in my comboboxes. In your code there is another connectionstring there...what should i put there?
Code:
Private Sub btnDisplay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisplay.Click
SuspendLayout()
frmBackGroundWorker.ShowDialog()
cnn.ConnectionString = "Data Source=.\sqlexpress;Initial Catalog=MyDatabase;Integrated Security=True"
If cnn.State = ConnectionState.Closed Then cnn.Open()
cmdGrade = cnn.CreateCommand
cmdGrade.CommandText = "SELECT DISTINCT * FROM tblEnrol WHERE SectionName = '" & cboSection.Text & "' AND SubjectName = '" & cboSubjectName.Text & "' AND YearLevel = '" & cboYearLevel.Text & "'"
daGrade.MissingSchemaAction = MissingSchemaAction.AddWithKey
dsGrade.Clear()
dsSection.Clear()
dsSubject.Clear()
daGrade.SelectCommand = cmdGrade
daGrade.Fill(dsGrade, "tblEnrol")
cnn.Close()
Dim si() As FarPoint.Win.Spread.SortInfo = New FarPoint.Win.Spread.SortInfo() {New FarPoint.Win.Spread.SortInfo(5, False), New FarPoint.Win.Spread.SortInfo(2, True)}
'bind FpSpread2 to datasource
'1st Grading
FpSpread2.Sheets(0).DataSource = dsGrade
FpSpread2.Sheets(0).DataMember = "tblEnrol"
'more codes here
Re: [2005] BackgroundWorker and Progress Bar
You really need to go back to square 1 and work out exactly what it is you're actually doing before you try to implement it. You're calling ShowDialog there, then you're getting the data. What good is that? ShowDialog doesn't return until the dialogue is dismissed so of course you aren't going to see any data until you dismiss the dialogue. It's supposed to be the dialogue that gets the data, not the calling form. The calling form is supposed to show the dialogue and then get the data from the dialogue once it's dismissed. It shouldn't know anything about getting the data from the database. the dialogue is supposed to display the ProgressBar to the user, start a BackgroundWorker and then DO THE WORK. I've already shown you how to implement it so I'm afraid I can do no more.
Re: [2005] BackgroundWorker and Progress Bar
Hello,
I have created an sample application.
However, you can not monitor the actual progress if you don't know how many records you need to load. However, I think you could do a sql (count) function to get the number of records, then set this as the max in your progress bar.
In the sample below I am just creating a single datatable and filling it will records. This would be where you would get your actual data.
Hope this helps,
So in the main form you would have this:
vb Code:
Private Sub btnGetData_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim frmGetData As New GetData()
frmGetData.ShowDialog()
'Get the data from the property
Dim dt As New DataTable()
dt = frmGetData.MyDataTable
'Assign the table to the grid's datasource
Me.dgvData.DataSource = dt
End Sub
In the form where you will display the progress bar and do all the work:
vb Code:
Private dt As New DataTable()
Public Sub New()
InitializeComponent()
End Sub
Public ReadOnly Property MyDataTable() As DataTable
'Public property that will return the data table (readonly).
Get
Return dt
End Get
End Property
Private Sub GetData_Load(ByVal sender As Object, ByVal e As EventArgs)
'Start the background worker
Me.bgwGetData.RunWorkerAsync()
End Sub
Private Sub bgwGetData_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
'Get the records from the database.
'For this example we are creating a data table and filling it will records.
Dim dc As New DataColumn()
dc.DataType = System.Type.[GetType]("System.Int16")
dc.ColumnName = "IDNumber"
dc.AutoIncrement = True
dc.AutoIncrementSeed = 0
dc.AutoIncrementStep = 1
dt.Columns.Add(dc)
dc = New DataColumn()
dc.DataType = System.Type.[GetType]("System.String")
dc.ColumnName = "Name"
dt.Columns.Add(dc)
'Loop through adding all the rows to the datatable
Dim nr As DataRow
For i As Integer = 0 To 99
'If the user clicked the cancel button stop filling
If bgwGetData.CancellationPending Then
'Set cancel to true so this can be checked in the work completed
e.Cancel = True
Exit For
End If
nr = dt.NewRow()
nr("Name") = "Steve"
dt.Rows.Add(nr)
'Report the actual progress - loop counter (i)
Me.bgwGetData.ReportProgress(i)
'This happens too fast, slow it down.
System.Threading.Thread.Sleep(100)
Next
End Sub
'Update the progress bar
Private Sub bgwGetData_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
Me.pbrGetData.Value = e.ProgressPercentage
End Sub
'Once the work has been completed or the operation was cancelled by the user.
Private Sub bgwGetData_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
If Not e.Cancelled Then
MessageBox.Show("Work Completed")
Else
MessageBox.Show("Operation cancelled unexpectedly - data may not be complete")
End If
Me.Close()
End Sub
'Cancel the operation
Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As EventArgs)
Me.bgwGetData.CancelAsync()
End Sub
Re: [2005] BackgroundWorker and Progress Bar
steve, i appreciate very much your reply and code. Right now, the apps is already being used and the design is like what i mentioned in post #18. I have a main form with a treeview menu. I call a form which contains a third party control (fpspread). I click a button to populate the grid with records from my table. With the code you gave, I think will not fit my need.
If using background worker is not possible with my apps. How do i just display something to let the user that something is going to and they need to wait for awhile and when loading or fetching of the records is done then the prompt display or whatever it is will be dismissed or unloaded automatically.
Re: [2005] BackgroundWorker and Progress Bar
Or Instead of having a pop up form can this be done like how internet explorer does --put a progress bar at the status bar?