Put long running method into task, showing new form meantime and closing it once the task completes

删除回忆录丶 提交于 2019-12-02 12:44:35

You already have the answer here:
Showing WinSCP .NET assembly transfer progress on WinForm's progress bar

To put it simple, I'm just extracting the relevant part:

  • You need to close the form at the end of the task.
  • As the task runs on a background thread, you need to use .Invoke method to invoke the closing on a GUI thread.

A simple implementation is like:

' Create the form before the task, so that we can reference it in the task
Dim pic As New Waiting

Dim tsk As Task(Of Boolean) =
    Task.Factory.StartNew(Of Boolean)(
        Function()
            ' Run lenghty task
            Dim Result As Boolean =
                WinScp.GetFile(myremotePicturePath, ladujZdjeciaPath, True)
            ' Close form once done (on GUI thread)
            pic.Invoke(New Action(Sub() pic.Close()))
            Return Result
        End Function)

' Show the form
pic.ShowDialog()

Internally the WinForms Form works like:

Class Form                                      

    Private closed as Boolean                   

    Function ShowDialog                         

        While Not closed                        

            If ' X button clicked                 
                Close                           
            End IF                              

            If ' anything in the Invoke queue     
                ' Get action from the Invoke queue
                ' Run the action                  
                ' In our case the "action" is .Close
            End If                              

            ' Process message queue (mouse clicks, key presses, draw form)

        End While                               

    End Sub                                     

    Sub Close                                   
        closed = True                           
    End Sub                                     

    Sub Invoke(action)                          
        ' Add action to invoke queue              
    End Sub                                     

End Class                                       

As of generic handler without tasks, this is how I achieved in one of applications a while ago

  1. Add a new form (frmProgress)

  2. Add hourglass GIF image (picProgress) to the center of this form

  3. Set following form (frmProgress) properties either in GUI or in code on load event:

    Private Sub frmProgress_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  
        FormBorderStyle = FixedSingle  
        Opacity = 0.5R  
        ShowInTaskbar = False  
        TopMost = True  
        WindowState = Maximized  
    End Sub  
    
  4. Center image in form on resize event, if required

    Private Sub frmProgress_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize  
        picProgress.Left = CInt(Me.Width / 2 - picProgress.Width / 2)  
        picProgress.Top = CInt(Me.Height / 2 - picProgress.Height / 2)  
    End Sub  
    
  5. Load the form before initiating your processing (DO NOT use ShowDialog())

    frmProgress.Show()'DO NOT use ShowDialog()  
    
  6. Initiate your processing

  7. Hide progress form after task is finished

    frmProgress.Hide()  
    
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!