BackgroundWorker занят vb.net

Я пытаюсь запустить трудоемкие задачи в backgroundWorker, чтобы можно было обновить индикатор выполнения. Однако 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

person Aidan Kehoe    schedule 17.05.2016    source источник
comment
Есть ли на кнопке несколько событий мыши? MouseDown, MouseUp, MouseClick? Есть ли что-то, что вызывает это же событие? Можем ли мы увидеть код в BackgroundWorker1.DoWork()?   -  person A Friend    schedule 17.05.2016
comment
@ProGrammer На кнопке нет других событий. Я не хотел публиковать код dowork, потому что он довольно длинный, но я это сделаю. Спасибо за ответ.   -  person Aidan Kehoe    schedule 17.05.2016
comment
вам нужно поместить свой код в событие запуска фонового рабочего   -  person user1234433222    schedule 17.05.2016
comment
@Werdna Я думал, что трудоемкие задачи должны были выполняться в событии doWork? Под событием запуска вы имеете в виду runworkercompleted? Спасибо за ответ.   -  person Aidan Kehoe    schedule 17.05.2016
comment
Я в поезде в банкомате, однако я могу быстро написать пример фонового рабочего, если хотите, или даже отправить его вам по электронной почте?   -  person user1234433222    schedule 17.05.2016
comment
@Werdna спасибо, это было бы здорово! Моя электронная почта: [email protected].   -  person Aidan Kehoe    schedule 17.05.2016


Ответы (2)


Вот некоторый код, который я написал для вас, чтобы вы посмотрели, он должен привести вас в правильном направлении и помочь вам в использовании фонового работника :)

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

Дайте мне знать, как у вас дела
Happy Coding

person user1234433222    schedule 17.05.2016

Все взаимодействие с пользовательским интерфейсом должно происходить в потоке пользовательского интерфейса, поэтому вы не можете отображать диалоговое окно из фонового потока.

См. С# backgroundworker не будет работать с кодом, который я хочу сделать для аналогичного вопроса (C#, а не VB, но концепция та же).

С уважением Роб

person Rob    schedule 17.05.2016
comment
Отлично, спасибо! Это была не единственная моя проблема в коде, но как только я это исправил, все остальное встало на свои места. Я бы проголосовал, но недостаточно репутации :( - person Aidan Kehoe; 17.05.2016