Aidan Kehoe Aidan Kehoe - 1 year ago 264
Vb.net Question

BackgroundWorker is busy vb.net

I am trying to run time consuming tasks in a backgroundWorker so that the progress bar can be updated. However, the backgroundWorker never runs because I always get an error saying the worker is currently busy even though I only call it once. I tried debugging the code where I run the background worker using this:

Private Sub saveBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles saveBtn.Click
Dim k As Boolean = BackgroundWorker1.IsBusy
Debug.Print(k)
BackgroundWorker1.RunWorkerAsync()

End Sub


What I found was that the saveBtn_Click sub would loop through twice for some reason. So, the background worker would originally not be busy, then it would run, saveBtn_Click would loop through again and the backgroundWorker would be busy. Why is saveBtn_click looping through twice? Here is the DoWork code:

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
'Declare variables used in conjunction with solid edge
Dim objApplication As SolidEdgeFramework.Application = Nothing
Dim objDocument As SolidEdgeFramework.SolidEdgeDocument = Nothing
Dim objPropertySets As SolidEdgeFramework.PropertySets = Nothing
Dim objProperties As SolidEdgeFramework.Properties = Nothing
Dim objProperty As SolidEdgeFramework.Property = Nothing

'Declare variables related to file
Dim FileName As String
Dim FileName1 As Object
Dim ChosenFile As Object = Nothing
Dim NewFileNames(3) As String
Dim Extensions(2) As String
Dim Extension As String
Dim i, k As Integer
Dim counter As Integer
Dim temp As String


'Store required extensions into array
Extensions(0) = ".stp"
Extensions(1) = ".x_t"
Extensions(2) = ".igs"
Extension = ".dxf"

'Uses open dialog to allow for folder selection in required path
Dim dialog As New FolderBrowserDialog()
dialog.SelectedPath = "C:\Folder"
dialog.Description = "Select Folder"
If dialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
ChosenFile = dialog.SelectedPath
End If


Try

'Connects to solid edge
objApplication = Marshal.GetActiveObject("SolidEdge.Application")

'References the currently open document
objDocument = objApplication.ActiveDocument

'References the properties of the document
objPropertySets = objDocument.Properties

'Gets file name from open document
FileName = objDocument.Name

If objDocument.Type = DocumentTypeConstants.igDraftDocument Then
'Checks for the .asm extension in the file name (-4 is used so that the index does not surpass the string length)
For i = 0 To FileName.Length - 4
If FileName(i) = "." And FileName(i + 1) = "d" And FileName(i + 2) = "f" And FileName(i + 3) = "t" Then
counter = i
End If
Next

'Removes the .asm from the file name
temp = FileName.Remove(counter, 4)
FileName = temp


'Uses the file name as a default response for the input box
FileName1 = InputBox("Enter file Name", DefaultResponse:=FileName)
txt.Text = "File is being saved"

ProgressBar1.Value = 20

'Loops through properties to find name of file
'For i = 1 To objPropertySets.Count
' objProperties = objPropertySets.Item(i)
' For j = 1 To objProperties.Count
' objProperty = objProperties.Item(j)
' FileName = objProperty.Name
' Debug.Print(FileName)
' Next
'Next



'Creates a new file name that acts as the path of the file
NewFileNames(0) = ChosenFile & "\" & FileName1 & Extension & Extension

objDocument.SaveAs(NewFileNames(0))

ProgressBar1.Value = 60

'objDocument.SaveAs("C:\Folder", NewFileName1)
'objDocument.SaveAs("C:\Folder", NewFileName2)
'objDocument.SaveAs("C:\Folder", NewFileName3)

'Zips the file using Ionic.zip library
'For k = 0 To (NewFileNames.Count - 1)
' Using zip As ZipFile = New ZipFile
' zip.AddFile(NewFileNames(k))
' zip.Save(ChosenFile & "\" & FileName1 & "-" & Extensions(k) & ".zip")
' End Using
'Next

'Process.Start("C:\Programme\7-Zip\7za.exe", "a -tzip C:\Folder\files.7z C:\Folder\.*dxf")

'Execute7Zip("C:\Program Files\7-Zip", "7za.exe", NewFileNames(0), "C:\Folder\zippedfiles.zip")
Dim zippedLocation As String = Nothing
For i = 0 To NewFileNames(0).Length - 4
If NewFileNames(0)(i) = "." And NewFileNames(0)(i + 1) = "d" And NewFileNames(0)(i + 2) = "x" And NewFileNames(0)(i + 3) = "f" Then
counter = i
zippedLocation = NewFileNames(0).Remove(i, 4)
End If
Next


Shell("C:\Program Files\7-Zip\7z.exe a " + zippedLocation + ".zip " + NewFileNames(0))

ProgressBar1.Value = 100

MsgBox("Your file has been saved")

'Closes the window
Me.Dispose()
Else

'removes solid edge extension
FileName = FileName.Substring(0, FileName.Length - 4)
Debug.Print(FileName)

'Uses the file name as a default response for the input box
FileName1 = InputBox("Enter file Name", DefaultResponse:=FileName)
txt.Text = "File is being saved"


'Loops through properties to find name of file
'For i = 1 To objPropertySets.Count
' objProperties = objPropertySets.Item(i)
' For j = 1 To objProperties.Count
' objProperty = objProperties.Item(j)
' FileName = objProperty.Name
' Debug.Print(FileName)
' Next
'Next


'Creates a new file name that acts as the path of the file
For k = 0 To (Extensions.Length - 1)
NewFileNames(k) = ChosenFile & "\" & FileName1 & Extensions(k) & Extensions(k)
Next


For k = 0 To (NewFileNames.Count - 2)
objDocument.SaveAs(NewFileNames(k))
BackgroundWorker1.ReportProgress((k / (NewFileNames.Count - 2)) * 100)
System.Threading.Thread.Sleep(200)
Next



'objDocument.SaveAs("C:\Folder", NewFileName1)
'objDocument.SaveAs("C:\Folder", NewFileName2)
'objDocument.SaveAs("C:\Folder", NewFileName3)

'Zips the file using Ionic.zip library
'For k = 0 To (NewFileNames.Count - 1)
' Using zip As ZipFile = New ZipFile
' zip.AddFile(NewFileNames(k))
' zip.Save(ChosenFile & "\" & FileName1 & "-" & Extensions(k) & ".zip")
' End Using
'Next

'Process.Start("C:\Programme\7-Zip\7z.exe", "a -tzip C:\Folder\files.zip C:\Folder\*.stp")


'Execute7Zip("C:\Program Files\7-Zip", "7za.exe", NewFileNames(0), "C:\Folder\zippedfiles.zip")
Dim zippedLocation(2) As String
For j = 0 To NewFileNames.Length - 2
For i = 0 To NewFileNames(j).Length - 4
If NewFileNames(j)(i) = "." And NewFileNames(j)(i + 1) = "s" And NewFileNames(j)(i + 2) = "t" And NewFileNames(j)(i + 3) = "p" Then
counter = i
zippedLocation(j) = NewFileNames(j).Remove(i, 4)
zippedLocation(j) = zippedLocation(j).Replace(".", "-")
End If
If NewFileNames(j)(i) = "." And NewFileNames(j)(i + 1) = "x" And NewFileNames(j)(i + 2) = "_" And NewFileNames(j)(i + 3) = "t" Then
counter = i
zippedLocation(j) = NewFileNames(j).Remove(i, 4)
zippedLocation(j) = zippedLocation(j).Replace(".", "-")
End If
If NewFileNames(j)(i) = "." And NewFileNames(j)(i + 1) = "i" And NewFileNames(j)(i + 2) = "g" And NewFileNames(j)(i + 3) = "s" Then
counter = i
zippedLocation(j) = NewFileNames(j).Remove(i, 4)
zippedLocation(j) = zippedLocation(j).Replace(".", "-")
End If

Next
Next

Shell("C:\Program Files\7-Zip\7z.exe a " + zippedLocation(0) + ".zip " + NewFileNames(0))
Shell("C:\Program Files\7-Zip\7z.exe a " + zippedLocation(1) + ".zip " + NewFileNames(1))
Shell("C:\Program Files\7-Zip\7z.exe a " + zippedLocation(2) + ".zip " + NewFileNames(2))
Thread.Sleep(2000)
My.Computer.FileSystem.DeleteFile(NewFileNames(0))
My.Computer.FileSystem.DeleteFile(NewFileNames(1))
My.Computer.FileSystem.DeleteFile(NewFileNames(2))


MsgBox("Your file has been saved")

'Closes the window
Me.Dispose()
End If

'The error message opens if solid works is not open in the background
Catch ex As Exception
txt.Text = "Open Solid Edge"

'Releases each reference to solid work (freeing memory)
Finally
If Not (objDocument Is Nothing) Then
Marshal.ReleaseComObject(objDocument)
objDocument = Nothing
End If
If Not (objApplication Is Nothing) Then
Marshal.ReleaseComObject(objApplication)
objApplication = Nothing
End If

End Try
End Sub

Answer Source

Here is some code that i have written up for you to have a look at, it should lead you in the right direction and help you on your way in using a background worker:)

Imports System.ComponentModel

 Public Class Form1
''This will display the information to the textbox and will also load a progressbar(you can change it to something else beside a textbox too eg label, windows form title and so on).
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    TextBox1.Text = e.ProgressPercentage & "%"
    ProgressBar1.Value = e.ProgressPercentage
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ''This is make the backgroundworker start at load up(change it to a button if need be
    CheckForIllegalCrossThreadCalls = False
    BackgroundWorker1.RunWorkerAsync()
    BackgroundWorker1.WorkerReportsProgress = True
End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    ''This is the example that i created to show you how to set a task.
    For i = 0 To 10000
        TextBox1.Text = i
        BackgroundWorker1.ReportProgress(i)
        System.Threading.Thread.Sleep(500)
    Next
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    ''once the task is complete it will show a messagebox and reset the progressbars value to 0 so its not full when the task is compelete.
    MessageBox.Show("Completed")
    ProgressBar1.Value = 0
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    ''If you ever need to cancel the backgroundworkder when it is still running
    BackgroundWorker1.CancelAsync()
End Sub
End Class

Let me know how you go
Happy Coding

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download