title: Put long running method into task, showing new form meantime and closing it once the task completes
body: <p>My application has some long running method which taking some time to be finalised therefore i decided to push it into the separate task then meantime show some new form as <code>ShowDialog</code> which inside is placed hourglass animation and then this form should be closed when task finished the job. On that moment situation is that my new waiting form is not going to Close at all its just show up and stay. I read somewhere that its because <code>ShowDialog</code> in that case will not return nothing that's why <code>Close</code> will be never reached until user click Close manually on form, but how its possible as if I put <code>form.Close</code> it should be the same as user would click on that form. Please of explanation and support here what should be changed to achieve the point. Below my code.</p>
  
  <p><strong>Main form:</strong></p>
  
  <pre><code>WinScp = New WinScpOperation("ftp", "myserver", "login", "password", 21, 0)
  
  Dim tsk As Task(Of Boolean) = Task.Factory.StartNew(Of Boolean)(Function()
     Return WinScp.GetFile(myremotePicturePath, ladujZdjeciaPath, True)
  End Function)
  
  Dim pic As New Waiting
  pic.ShowDialog() 'show waiting form
  
  Task.WaitAll(tsk) 'waiting on task to be finalized
  
  pic.Close() 'close waiting form
  ...
  </code></pre>
  
  <p><strong>Waiting form (nothing but the hourglass gif)</strong></p>
  
  <pre><code>Public Class Waiting
  End Class
  </code></pre>
  
  <p><strong>Further discussion #1:</strong></p>
  
  <p><strong>Option 1: (your working version)</strong></p>
  
  <pre><code> 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()
                              Task.WaitAll(tsk)
  </code></pre>
  
  <p><strong>Option2: (not working why??)</strong></p>
  
  <pre><code>    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)
  
              Return Result
          End Function)
  
                              ' Show the form
                              pic.ShowDialog()
                              Task.WaitAll(tsk)
    ' Close form once done (on GUI thread)
              pic.Invoke(New Action(Sub() pic.Close()))
  </code></pre>
  
  <p><strong>Additional question:</strong></p>
  
  <pre><code>                        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()
                          Task.WaitAll(tsk)
  
                          If tsk.Result Then 'if return value is true
                              'Do something when file was downloaded correctly
                          Else
                              'Do something when file was NOT downloaded
                          End If
  </code></pre>
  
  <p><strong>Additional #2:
  This was oryginally:</strong></p>
  
  <pre><code>           If WinScp.GetFile(lsbxPicPaths.SelectedItem, temp_dir &amp; "\" &amp; Path.GetFileName(lsbxPicPaths.SelectedItem), False) Then
                  temp_pic = temp_dir &amp; "\" &amp; Path.GetFileName(lsbxPicPaths.SelectedItem)
              End If
  </code></pre>
  
  <p><strong>I implemented our solution:</strong></p>
  
  <pre><code>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(lsbxPicPaths.SelectedItem, temp_dir &amp; "\" &amp; Path.GetFileName(lsbxPicPaths.SelectedItem), False)
                      ' Close form once done (on GUI thread)
                        pic.Invoke(New Action(Sub() pic.Close()))
                        Return Result
                   End Function)
  
                             ' Show the form
                                pic.ShowDialog()
                              Task.WaitAll(tsk)
  
                      If tsk.Result Then 'if return value is true
  
                                     temp_pic = temp_dir &amp; "\" &amp; Path.GetFileName(lsbxPicPaths.SelectedItem)
                  '                Else
  
                                  End If
  
                  '*************************************
  </code></pre>
  
  <p><strong>Solution to above:</strong>
  have no idea why when defined two variables instead directly put it into GetFile arguments solve it because previously also there was not variables and was working. Can someone explain that behaviour?</p>
  
  <pre><code>                Dim remotefile As String = lsbxPicPaths.SelectedItem
                  Dim temp_file As String = temp_dir &amp; "\" &amp; Path.GetFileName(lsbxPicPaths.SelectedItem)
  
  
                  'http://stackoverflow.com/questions/33030706/put-long-running-method-into-task-showing-new-form-meantime-and-closing-it-once
                  Dim pic2 As New Waiting
  
  
  
                  Dim tsk2 As Task(Of Boolean) = Task.Factory.StartNew(Of Boolean)(Function()
  
                                                                                       'Run lenghty task
  
                                                                                       Dim Result As Boolean = WinScp.GetFile(remotefile, temp_file, False)
                                                                                       'Close form once done (on GUI thread)
                                                                                       pic2.Invoke(New Action(Sub() pic2.Close()))
                                                                                       Return Result
                                                                                   End Function)
                  pic2.ShowDialog()
                  Task.WaitAll(tsk2)
  
  
                  If tsk2.Result = True Then
                      MsgBox("GetFile zwrocilo true")
                      temp_pic = temp_dir &amp; "\" &amp; Path.GetFileName(lsbxPicPaths.SelectedItem)
                  End If
  </code></pre>