0

Is it possible to invoke a function from a "non main" thread and then wait for it to finish before executing the rest?

I could set a boolean just before and then make the function "flip" the boolean to false when its done, but I wondered if there was a simplier/more professional way of achieving this?

Thanks

user3494322
  • 171
  • 3
  • 11
  • More information is needed. What do you mean by 'executing the rest'? Specify by an example what you are trying to achieve. – user469104 Aug 05 '14 at 20:25
  • 3
    If you need the thread to block until the function is done, why not just call the function synchronously from that thread? – mbeckish Aug 05 '14 at 20:31

1 Answers1

2

I guess you want to keep your form responsive yet you don't want to have extra procedures being called or stuff like that. In that case the Async and Await keywords are probably a good way for you:

It is explained in detail here http://msdn.microsoft.com/en-US/en-en/library/hh191443.aspx but I will give you a short overview:

  • You first declare a method with the Async keyword. This can be for example the method handling a button click event in my example below.
  • In this method you get your result from another method that is called as a task and assign this to a temporary variable using the await keyword.
  • During the time the task is running the further execution of the code is halted. Your GUI stays responsive tough.

Here is a small example (just throw a Button and a Label on a Form):

Public Class Form1
    ''' <summary>
    ''' This method does the work. It is called from the async method in form of a Task(Of String).
    ''' </summary>
    Private Function GetString() As String
        'Some delay
        Threading.Thread.Sleep(3000)
        Return "Hello World!"
    End Function

    'Note the Async Keyword
    Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        'First create the task
        Dim t As Task(Of String) = New Task(Of String)(AddressOf GetString)
        'Start the task
        t.Start()
        'Wait for the task to complete. Does not suspend your GUI!
        'Much preferrable to some kind of waiting loop with DoEvents and stuff.
        Dim Result As String = Await t
        'Signal the end
        MsgBox("DONE")
        'Output the results
        Label1.Text = Result
    End Sub
End Class

I'll be honest, I can't really dive into the dark underbellies of how this is actually implemented in the .NET Framework since I have not read much about it myself. (I program mainly for the .NET Framework 4.0. Async/Await was introduced in 4.5. It can however be used in 4.0 as well with an extension package by Microsoft https://www.nuget.org/packages/Microsoft.Bcl.Async).
The actual usage however is not that hard as you can see, so I think this is the way to go.

Jens
  • 6,275
  • 2
  • 25
  • 51
  • FYI, Async can be thought of as a compiler directive. It will actually reorganize your code and create all the callbacks for you. This makes programming easy but unfortunately your call stack is impossible to unravel making debugging errors (on the users computer) a nightmare. But it is better than the alternative so I use it often. – Steve Aug 05 '14 at 21:34
  • Good to know. I will keep that in mind when I come around to using it myself once in a while. – Jens Aug 05 '14 at 21:37