VB.NET Threading or Backgroundworker ?? Struggling to get them to work

Please support our VB.NET advertiser: Intel Parallel Studio Home
Reply

Join Date: Jan 2008
Posts: 16
Reputation: ads248 is an unknown quantity at this point 
Solved Threads: 0
ads248 ads248 is offline Offline
Newbie Poster

VB.NET Threading or Backgroundworker ?? Struggling to get them to work

 
0
  #1
Jan 23rd, 2008
Hi

I've developed an app that reads in a csv file, strips it out to its component fields, validates them and writes it up to the database.

So far, so good.

I now want to enhance it so that the dataloading take place in the background enabling the UI to be used for some progress indication when loading large files.

I've managed to get the loading working in both a thread and backgroundworker but have not managed to do anything successful with the UI. I've read numerous posts on the net, which seem to make sense but I can't see how to apply them to my "real world" situation.

If I use a thread, I can't do anything with the controls on the form as they belong to another thread. When I tried the backgroundworker, the UI still appears to be frozen.

So I've stripped all that code out and my app is running on the single thread again.

I've tried to keep the code on the form to just the visual effects calling methods in another class to do the data reading, manipulation, validation and loading.

Any help would be greatly appreciated, as I just can't get it to do what I need.

Regards

Andrew
Reply With Quote Quick reply to this message  
Join Date: Aug 2007
Posts: 25
Reputation: poguemahone is an unknown quantity at this point 
Solved Threads: 2
poguemahone's Avatar
poguemahone poguemahone is offline Offline
Light Poster

Re: VB.NET Threading or Backgroundworker ?? Struggling to get them to work

 
0
  #2
Jan 24th, 2008
You could start the file IO in a separate class from the UI and use Thread.Start(). In your file IO class, you can raise an event after each operation (or whatever interval you choose) and have it call back to the UI to perform updates.
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 16
Reputation: ads248 is an unknown quantity at this point 
Solved Threads: 0
ads248 ads248 is offline Offline
Newbie Poster

Re: VB.NET Threading or Backgroundworker ?? Struggling to get them to work

 
0
  #3
Jan 24th, 2008
I think I can manage the RaiseEvent and get it to do some visuals on the form, however, how do I make it call back to th UI to perform updates on the UI.

I have already ran it in a thread and raised an event when it fininshed.

It's the callin back to the UI that escapes me at the moment.
Reply With Quote Quick reply to this message  
Join Date: Aug 2007
Posts: 25
Reputation: poguemahone is an unknown quantity at this point 
Solved Threads: 2
poguemahone's Avatar
poguemahone poguemahone is offline Offline
Light Poster

Re: VB.NET Threading or Backgroundworker ?? Struggling to get them to work

 
0
  #4
Jan 24th, 2008
In the code of your UI try using
AddHandler objFileIOClass.Event, AddressOf UIClass.Function
where FileIOClass.Event is the Event Raised from the FileIOClass and UIClass.Function is the Address of the function you want to execute in the UI when the Event is raised. It should look something like this:

Dim objFileIOClass as New FileIOClass

AddHandler objFileIOClass .Event, AddressOf UIClass.Function

Dim FileIOThread = New Threading.Thread(AddressOf FileIOClass.BeginOperation)

FileIOThread.Start()
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 16
Reputation: ads248 is an unknown quantity at this point 
Solved Threads: 0
ads248 ads248 is offline Offline
Newbie Poster

Re: VB.NET Threading or Backgroundworker ?? Struggling to get them to work

 
0
  #5
Jan 27th, 2008
Hi

Thanks for the help so far, but I'm still struggling with this I'm afraid.

I have the "lengthy process" running in a thread that is called from a button click on the front end main form (UI).

I raise an event at the end of the "lengthy process", but the event handler wont do everything that I need it to because it errors saying the controls I am trying to update belong to another thread.

The "lengthy process" is in a seperate class from the frm.vb code.

Thanks

Andrew
Reply With Quote Quick reply to this message  
Join Date: Aug 2007
Posts: 25
Reputation: poguemahone is an unknown quantity at this point 
Solved Threads: 2
poguemahone's Avatar
poguemahone poguemahone is offline Offline
Light Poster

Re: VB.NET Threading or Backgroundworker ?? Struggling to get them to work

 
0
  #6
Jan 27th, 2008
That means that the thread that you started for the "lengthy process" is the thread that is trying to update the UI. Could you post the code from the button_click event?
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 16
Reputation: ads248 is an unknown quantity at this point 
Solved Threads: 0
ads248 ads248 is offline Offline
Newbie Poster

Re: VB.NET Threading or Backgroundworker ?? Struggling to get them to work

 
0
  #7
Jan 27th, 2008
Code for my button click event.

  1. Private Sub btnGo1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGo1.Click
  2.  
  3. aiidb2.ExcludeDuplicates = False
  4.  
  5. If (txtDelim1.Text = "") Then
  6. MessageBox.Show("You MUST enter a field delimiter for the CSV input file")
  7. txtDelim1.Focus()
  8. GoTo lab_end
  9. End If
  10.  
  11. If (txtAimsNo.Text = "") Then
  12. MessageBox.Show("You MUST enter an AIMS number for the input file")
  13. txtAimsNo.Focus()
  14. GoTo lab_end
  15. End If
  16.  
  17. If (txtReceiptNo.Text = "") Then
  18. MessageBox.Show("You MUST enter a contractor receipt number for the input file")
  19. txtReceiptNo.Focus()
  20. GoTo lab_end
  21. End If
  22.  
  23. If aiidb2.DuplicatesFound Then
  24. Dim dlgRes As DialogResult
  25. dlgRes = MessageBox.Show( _
  26. "This contractor return contains duplicate rows." + vbCr + vbLf + _
  27. "Do you want to load the duplicates into SOURCEData?", "File Contains Duplicate Rows", _
  28. MessageBoxButtons.YesNoCancel, _
  29. MessageBoxIcon.Question)
  30. If dlgRes = Windows.Forms.DialogResult.Yes Then
  31. aiidb2.ExcludeDuplicates = False
  32. ElseIf dlgRes = Windows.Forms.DialogResult.No Then
  33. aiidb2.ExcludeDuplicates = True
  34. Else
  35. GoTo lab_end
  36. End If
  37. End If
  38.  
  39. ' Get current date/time and format it
  40. aiidb2.GetDateTime()
  41. aiidb2.FormatDateTime()
  42.  
  43. aiidb2.NowDate = aiidb2.Now.Year.ToString + aiidb2.NowMonth + aiidb2.NowDay
  44. aiidb2.NowTime = aiidb2.NowHour + aiidb2.NowMinute
  45.  
  46. If aiidb2.ExcludeDuplicates Then
  47. 'Create file of duplicates
  48. aiidb2.DuplicatesFile()
  49. End If
  50.  
  51. ' ***** Initialise variables
  52. aiidb2.ErrorRate = 0
  53.  
  54. 'Test if replayed error file
  55. If (aiidb2.ErrorFile) Then
  56. If MessageBox.Show("This is an error file." + vbCr + vbLf + _
  57. "Has it been corrected?" + vbCr + vbLf + _
  58. "Are you sure you want to replay this error file?", "Error File", _
  59. MessageBoxButtons.YesNo, MessageBoxIcon.Question) _
  60. = Windows.Forms.DialogResult.Yes Then
  61. 'do Nothing
  62. Else
  63. GoTo lab_end
  64. End If
  65. End If
  66.  
  67. aiidb2.CreateOriginalFileName()
  68.  
  69. Me.Cursor = Cursors.WaitCursor
  70.  
  71. ' Call to the lengthy process here
  72. 'Dim t As New Thread(AddressOf aiidb2.LoadData)
  73. 'AddHandler aiidb2.FinishedDataLoading, AddressOf FinishedDataLoadingEventHandler
  74. 't.Start()
  75.  
  76. lab_end:
  77.  
  78. End Sub


THis is the code I'm trying to run in the event handler when the lengthy process finishes. It fails when I try to do anything with the cursor or labels/ textboxes / buttons etc. on the form.

  1. 'If no errors, tidy files up
  2. If (aiidb2.ErrorCount = 0) Then
  3. 'Archive orignal file here
  4. File.Move(aiidb2.FilePath + aiidb2.OriginalFileName, aiidb2.FilePathArchived + aiidb2.OriginalFileName)
  5.  
  6. ' TODO: Possibly set DataLoadRequired flag on DB to false after successful load
  7.  
  8. ' TODO: Business decision on whether to delete replayed / corrected errorfile or Archive
  9. ' Currently archive the file
  10.  
  11. ' ***** DELETE ErrorFile *****
  12. 'Delete replayed error file (this can be reintroduced if neccessary, decided to keep corrected error file)
  13. 'If (aiidb2.errorFile) Then
  14. 'File.Delete(filePath + FileName)
  15. 'End If
  16.  
  17. ' ***** ARCHIVE ErrorFile *****
  18. 'Archive replayed / corrected errorfile
  19. If (aiidb2.ErrorFile) Then
  20. File.Move(aiidb2.FileName, aiidb2.FilePathArchived + aiidb2.FileNameNoPath)
  21. End If
  22.  
  23. 'MessageBox.Show("Original RAW data archived & any replayed error file deleted")
  24. End If
  25.  
  26. 'Calculate error rate as percentage
  27. aiidb2.ErrorRate = Math.Round(((aiidb2.ErrorCount / aiidb2.EndCount) * 100), 2)
  28.  
  29. Me.Cursor = Cursors.Default
  30.  
  31. If (aiidb2.DuplicatesFound And aiidb2.ExcludeDuplicates) Then
  32. MessageBox.Show(aiidb2.SuccessCount & " Rows Inserted into SOURCEData" & vbCr & vbLf & vbCr & vbLf & aiidb2.Dups.Count.ToString & " Rows written to DUPLICATES file" & vbCr & vbLf & vbCr & vbLf & aiidb2.ErrorCount & " Rows written to ERROR file" & vbCr & vbLf & vbCr & vbLf & "Error rate: " & aiidb2.ErrorRate & "%", "Load Summary")
  33. Else
  34. MessageBox.Show(aiidb2.SuccessCount & " Rows Inserted into SOURCEData" & vbCr & vbLf & vbCr & vbLf & aiidb2.ErrorCount & " Rows written to ERROR file" & vbCr & vbLf & vbCr & vbLf & "Error rate: " & aiidb2.ErrorRate & "%", "Load Summary")
  35. End If
  36.  
  37. lblFilename1.Visible = False
  38. lblFilename1.Text = Nothing
  39. aiidb2.FileName = Nothing
  40. lblDelim1.Visible = False
  41. lblAimsNo.Visible = False
  42. lblReceiptNo.Visible = False
  43. txtDelim1.Visible = False
  44. txtAimsNo.Text = ""
  45. txtAimsNo.Visible = False
  46. txtReceiptNo.Text = ""
  47. txtReceiptNo.Visible = False
  48. btnBrowseData.Visible = False
  49. btnGo1.Visible = False
  50. panData.Visible = False

Thanks

Andrew
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 16
Reputation: ads248 is an unknown quantity at this point 
Solved Threads: 0
ads248 ads248 is offline Offline
Newbie Poster

Re: VB.NET Threading or Backgroundworker ?? Struggling to get them to work

 
0
  #8
Jan 27th, 2008
Hi

Just noticed that the call to my lengthy process in the button click event is commented out. Obviously this wasn't the case when I was testing it.

Thanks

Andrew
Reply With Quote Quick reply to this message  
Join Date: Aug 2007
Posts: 25
Reputation: poguemahone is an unknown quantity at this point 
Solved Threads: 2
poguemahone's Avatar
poguemahone poguemahone is offline Offline
Light Poster

Re: VB.NET Threading or Backgroundworker ?? Struggling to get them to work

 
0
  #9
Jan 27th, 2008
Apparently, I have given you bad advice. The solution I presented appears to no longer be supported. The following is a comprehensive view of updating a UI from another thread and also using the background worker. This is an actual program that demonstrates the concepts. You can start a new Windows Application Project and paste the code in the code-behind of Form1. If you get build errors, delete the code from the Form1.Designer.vb file.

  1. Imports System
  2. Imports System.ComponentModel
  3. Imports System.Threading
  4. Imports System.Windows.Forms
  5.  
  6. Public Class Form1
  7. Inherits Form
  8.  
  9. ' This delegate enables asynchronous calls for setting
  10. ' the text property on a TextBox control.
  11. Delegate Sub SetTextCallback([text] As String)
  12.  
  13. ' This thread is used to demonstrate both thread-safe and
  14. ' unsafe ways to call a Windows Forms control.
  15. Private demoThread As Thread = Nothing
  16.  
  17. ' This BackgroundWorker is used to demonstrate the
  18. ' preferred way of performing asynchronous operations.
  19. Private WithEvents backgroundWorker1 As BackgroundWorker
  20.  
  21. Private textBox1 As TextBox
  22. Private WithEvents setTextUnsafeBtn As Button
  23. Private WithEvents setTextSafeBtn As Button
  24. Private WithEvents setTextBackgroundWorkerBtn As Button
  25.  
  26. Private components As System.ComponentModel.IContainer = Nothing
  27.  
  28.  
  29. Public Sub New()
  30. InitializeComponent()
  31. End Sub
  32.  
  33.  
  34. Protected Overrides Sub Dispose(disposing As Boolean)
  35. If disposing AndAlso (components IsNot Nothing) Then
  36. components.Dispose()
  37. End If
  38. MyBase.Dispose(disposing)
  39. End Sub
  40.  
  41.  
  42. ' This event handler creates a thread that calls a
  43. ' Windows Forms control in an unsafe way.
  44. Private Sub setTextUnsafeBtn_Click( _
  45. ByVal sender As Object, _
  46. ByVal e As EventArgs) Handles setTextUnsafeBtn.Click
  47.  
  48. Me.demoThread = New Thread( _
  49. New ThreadStart(AddressOf Me.ThreadProcUnsafe))
  50.  
  51. Me.demoThread.Start()
  52. End Sub
  53.  
  54.  
  55. ' This method is executed on the worker thread and makes
  56. ' an unsafe call on the TextBox control.
  57. Private Sub ThreadProcUnsafe()
  58. Me.textBox1.Text = "This text was set unsafely."
  59. End Sub
  60.  
  61. ' This event handler creates a thread that calls a
  62. ' Windows Forms control in a thread-safe way.
  63. Private Sub setTextSafeBtn_Click( _
  64. ByVal sender As Object, _
  65. ByVal e As EventArgs) Handles setTextSafeBtn.Click
  66.  
  67. Me.demoThread = New Thread( _
  68. New ThreadStart(AddressOf Me.ThreadProcSafe))
  69.  
  70. Me.demoThread.Start()
  71. End Sub
  72.  
  73.  
  74. ' This method is executed on the worker thread and makes
  75. ' a thread-safe call on the TextBox control.
  76. Private Sub ThreadProcSafe()
  77. Me.SetText("This text was set safely.")
  78. End Sub
  79.  
  80. ' This method demonstrates a pattern for making thread-safe
  81. ' calls on a Windows Forms control.
  82. '
  83. ' If the calling thread is different from the thread that
  84. ' created the TextBox control, this method creates a
  85. ' SetTextCallback and calls itself asynchronously using the
  86. ' Invoke method.
  87. '
  88. ' If the calling thread is the same as the thread that created
  89. ' the TextBox control, the Text property is set directly.
  90.  
  91. Private Sub SetText(ByVal [text] As String)
  92.  
  93. ' InvokeRequired required compares the thread ID of the
  94. ' calling thread to the thread ID of the creating thread.
  95. ' If these threads are different, it returns true.
  96. If Me.textBox1.InvokeRequired Then
  97. Dim d As New SetTextCallback(AddressOf SetText)
  98. Me.Invoke(d, New Object() {[text]})
  99. Else
  100. Me.textBox1.Text = [text]
  101. End If
  102. End Sub
  103.  
  104. ' This event handler starts the form's
  105. ' BackgroundWorker by calling RunWorkerAsync.
  106. '
  107. ' The Text property of the TextBox control is set
  108. ' when the BackgroundWorker raises the RunWorkerCompleted
  109. ' event.
  110. Private Sub setTextBackgroundWorkerBtn_Click( _
  111. ByVal sender As Object, _
  112. ByVal e As EventArgs) Handles setTextBackgroundWorkerBtn.Click
  113. Me.backgroundWorker1.RunWorkerAsync()
  114. End Sub
  115.  
  116.  
  117. ' This event handler sets the Text property of the TextBox
  118. ' control. It is called on the thread that created the
  119. ' TextBox control, so the call is thread-safe.
  120. '
  121. ' BackgroundWorker is the preferred way to perform asynchronous
  122. ' operations.
  123. Private Sub backgroundWorker1_RunWorkerCompleted( _
  124. ByVal sender As Object, _
  125. ByVal e As RunWorkerCompletedEventArgs) _
  126. Handles backgroundWorker1.RunWorkerCompleted
  127. Me.textBox1.Text = _
  128. "This text was set safely by BackgroundWorker."
  129. End Sub
  130.  
  131. #Region "Windows Form Designer generated code"
  132.  
  133.  
  134. Private Sub InitializeComponent()
  135. Me.textBox1 = New System.Windows.Forms.TextBox()
  136. Me.setTextUnsafeBtn = New System.Windows.Forms.Button()
  137. Me.setTextSafeBtn = New System.Windows.Forms.Button()
  138. Me.setTextBackgroundWorkerBtn = New System.Windows.Forms.Button()
  139. Me.backgroundWorker1 = New System.ComponentModel.BackgroundWorker()
  140. Me.SuspendLayout()
  141. '
  142. ' textBox1
  143. '
  144. Me.textBox1.Location = New System.Drawing.Point(12, 12)
  145. Me.textBox1.Name = "textBox1"
  146. Me.textBox1.Size = New System.Drawing.Size(240, 20)
  147. Me.textBox1.TabIndex = 0
  148. '
  149. ' setTextUnsafeBtn
  150. '
  151. Me.setTextUnsafeBtn.Location = New System.Drawing.Point(15, 55)
  152. Me.setTextUnsafeBtn.Name = "setTextUnsafeBtn"
  153. Me.setTextUnsafeBtn.TabIndex = 1
  154. Me.setTextUnsafeBtn.Text = "Unsafe Call"
  155. '
  156. ' setTextSafeBtn
  157. '
  158. Me.setTextSafeBtn.Location = New System.Drawing.Point(96, 55)
  159. Me.setTextSafeBtn.Name = "setTextSafeBtn"
  160. Me.setTextSafeBtn.TabIndex = 2
  161. Me.setTextSafeBtn.Text = "Safe Call"
  162. '
  163. ' setTextBackgroundWorkerBtn
  164. '
  165. Me.setTextBackgroundWorkerBtn.Location = New System.Drawing.Point(177, 55)
  166. Me.setTextBackgroundWorkerBtn.Name = "setTextBackgroundWorkerBtn"
  167. Me.setTextBackgroundWorkerBtn.TabIndex = 3
  168. Me.setTextBackgroundWorkerBtn.Text = "Safe BW Call"
  169. '
  170. ' backgroundWorker1
  171. '
  172. '
  173. ' Form1
  174. '
  175. Me.ClientSize = New System.Drawing.Size(268, 96)
  176. Me.Controls.Add(setTextBackgroundWorkerBtn)
  177. Me.Controls.Add(setTextSafeBtn)
  178. Me.Controls.Add(setTextUnsafeBtn)
  179. Me.Controls.Add(textBox1)
  180. Me.Name = "Form1"
  181. Me.Text = "Form1"
  182. Me.ResumeLayout(False)
  183. Me.PerformLayout()
  184. End Sub 'InitializeComponent
  185.  
  186. #End Region
  187.  
  188. <STAThread()> _
  189. Shared Sub Main()
  190. Application.EnableVisualStyles()
  191. Application.Run(New Form1())
  192. End Sub
  193. End Class
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 16
Reputation: ads248 is an unknown quantity at this point 
Solved Threads: 0
ads248 ads248 is offline Offline
Newbie Poster

Re: VB.NET Threading or Backgroundworker ?? Struggling to get them to work

 
0
  #10
Jan 27th, 2008
Tried that.

Don't have a clue what it's doing.

Just don't understand this concept whatsoever.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Other Threads in the VB.NET Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC