我正在尝试在backgroundWorker中运行耗时的任务,以便可以更新进度条。但是,后台工作程序永远不会运行,因为我总是会收到错误,说工人当前正忙,即使我只调用一次。我尝试使用以下代码调试运行后台工作程序的代码:
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
我发现saveBtn_Click子由于某种原因会循环两次。因此,后台工作者原本不会忙,然后它会运行,saveBtn_Click会再次循环,后台工作者会忙。为什么saveBtn_click循环两次?这是DoWork代码:
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
答案 0 :(得分:1)
所有UI交互必须在UI线程上进行,因此您无法从后台线程显示对话框。
有关类似的问题,请参阅c# backgroundworker won't work with the code I want it to do(C#而不是VB,但概念相同)。
此致 罗布
答案 1 :(得分:0)
以下是我为您编写的一些代码,它应该引导您朝着正确的方向前进并帮助您使用后台工作者:)
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
让我知道你是怎么去的 快乐编码