Visual Basic, Child Thread Blocking Main Thread

后端 未结 1 410
无人及你
无人及你 2021-01-26 00:13

I\'ve run into a little issue with a simple file copying application I\'m writing in Visual Basic 2005. I have a main thread which looks after the GUI, and for the file scanning

相关标签:
1条回答
  • 2021-01-26 00:47

    From what i can tell all calls to the System are also GUI Thread based no matter if you want them or not. And Control.CheckForIllegalCrossThreadCalls = False is very bad, you always want to write your thread and ( if beginner ) run code and everytime it breaks out to code to write a delegate and an invoke function for that part of your thread ( taking up the most minimal time ) one can in the Gui(Main) thread.

    Here is an example with full sourcecode

    http://www.codeproject.com/Articles/15104/Multithreading-with-VB-NET-A-beginner-s-choice

    in your thread

    Control.CheckForIllegalCrossThreadCalls = False -- this needs removed If check_scanfirst.Checked Then -- this needs a delegate and invoke method status1.Text = "Scanning..." -- this needs a delegate and invoke method bytestocopy = 0 scandir(src) -- if scandir(has calls to gui )this needs a delegate and invoke method but inside of Scandir()

        filesscanned = True
        MsgBox("Scanning completed")              -- this needs a delegate and invoke method ( keep in mind thread will keep running even if mesgbox not clicked )
    End If
    
    If check_delete.Checked Then              -- this needs a delegate and invoke method
        ' Do a clean of the destination, removing any files that don't exist in the source dir
    End If
    
    If filesscanned Then
        ProgressBar1.Visible = True             -- this needs a delegate and invoke method
        ProgressBar1.Minimum = 0             -- this needs a delegate and invoke method
        ProgressBar1.Maximum = 100             -- this needs a delegate and invoke method
        ProgressBar1.Refresh()             -- this needs a delegate and invoke method
    End If
    
    checkdir(src)
    MsgBox("Copying completed")             -- this needs a delegate and invoke method
    If filesfailed > 0 Then
        MsgBox("Warning: " + Str(filesfailed) + " files were not copied successfully.")             -- this needs a delegate and invoke method
    End If
    guistop()             -- this needs a delegate and invoke method if (guistop makes calls to gui )
    

    so if you can't tell your making lots of calls to the gui... heres how i would write it to make it really simple

    how i would write your code ( wrote this in word some code may need a tweak )

    Private sub DoStuffBeforeCopy()
    If check_scanfirst.Checked Then
        status1.Text = "Scanning..."
        bytestocopy = 0
    trd_copy.ParameterizedStart(src) //start thread
    end sub
    
    CopyTask(byval src as *string*?)
        scandir(src) – put the code here or make another thread ( src is better )
        filesscanned = True
    
        invoke-MsgBox("Scanning completed")
    
        invoke If check_delete.Checked Then
    
        If filesscanned Then
            Invoke-ProgressBar1.Visible = True
            Invoke-ProgressBar1.Minimum = 0
            Invoke-ProgressBar1.Maximum = 100
            Invoke-ProgressBar1.Refresh()
        End If
    
        checkdir(src) – put the code here or make another thread ( src is better )
    
        invoke-MsgBox("Copying completed")
    
        If filesfailed > 0 Then
            Invoke-MsgBox("Warning: " + Str(filesfailed) + " files were not copied successfully.")
        End If
    
        guistop()– put the code here or make another thread ( src is better )
    
    End sub
    

    ** DO THIS FOR ANY Delegat / invoke needed

    for threads calls with parameters

    trd_copy.ParameterizedStart(src)

    Delegate Sub nameofDelegate(s As Integer)
    Sub nameofDelegate+NameofSub(ByVal s As Integer)
        If Form1.ProgressBar1.InvokeRequired Then
            Dim d As New nameofDelegate (AddressOf nameofDelegate+NameofSub)
            NameOfYourForm.Invoke(d, New Object() {s})
        Else
            If s = 1 Then
                NameOfYourForm.ProgressBar1.Refresh() ** Or other Gui Functions
            Else
    
            End If
        End If
    End Sub
    

    For Thread calls without parametrs

    trd_copy.Start()

    Delegate Sub nameofDelegate()
    Sub nameofDelegate+NameofSub()
        If Form1.ProgressBar1.InvokeRequired Then
            Dim d As New nameofDelegate (AddressOf nameofDelegate+NameofSub)
            NameOfYourForm.Invoke(d, New Object())
        Else
           NameOfYourForm.ProgressBar1.Refresh() ** Or other Gui Functions
        End If
    End Sub
    
    0 讨论(0)
提交回复
热议问题