Robert Beaubien
Robert Beaubien

Reputation: 3156

Start Async Task without using Await in called method

Window store app that has a long running method that I need to call when the application starts up, but I don't need to wait on it to complete. I want it to run as a background task. If the go to a certain part of the application (reporting), then I will check and if necessary wait on the task.

Public Shared Async Function UpdateVehicleSummaries(p_vehicleID As Int32) As Task(Of Boolean)
    Dim tempVehicle As Koolsoft.MARS.BusinessObjects.Vehicle

    For Each tempVehicle In Vehicles
        If p_vehicleID = 0 Or p_vehicleID = tempVehicle.VehicleID Then
            UpdateVehicleStats(tempVehicle)
        End If
    Next

    Return True

End Function

It is called like this

Dim updateTask As Task(Of Boolean) = UpdateVehicleSummaries(0)

It has no Await call in it and I get the warning that it will run synchronously. How do I start something like this and have it run asynchronously? I want it to run on its own thread/task without blocking the interface thread. Any ideas?

Thanx!

Upvotes: 3

Views: 17818

Answers (2)

LorneCash
LorneCash

Reputation: 1594

I think this is an even more simple solution that is much easier to read

Public Shared RunningTask As Task

Public Shared Sub CallingSub()
    'No need for sub to be async but can be async if needed for other reasons (see below)
    'but that doesn't stop the execution in the CallingSub
    'Get the task started... it's not going to wait for the task to be done just sets the task variable
    RunningTask = UpdateVehicleSummaries(0)

    'if a parameter comes from a function it may look like this
    'note that if you do this then the CallingSub would need the async keyword
    RunningTask = UpdateVehicleSummaries(Await FunctionReturnInt32())

    'Do stuff that does not require task to be done


End Sub
Public Shared Async Sub UseTaskResults()
    'Must be async so you can await the result
    Await RunningTask
    'Do stuff that requires task to be done
End Sub

Public Shared Function UpdateVehicleSummaries(p_vehicleID As Int32) As Task
    'No need for this function to be async since the function has no await
    Dim tempVehicle As Koolsoft.MARS.BusinessObjects.Vehicle

    For Each tempVehicle In Vehicles
        If p_vehicleID = 0 Or p_vehicleID = tempVehicle.VehicleID Then
            UpdateVehicleStats(tempVehicle)
        End If
    Next
End Function

Upvotes: 3

Damir Arh
Damir Arh

Reputation: 17855

You should run the code in your function inside a Task which you can then return from it:

Public Shared Function UpdateVehicleSummaries(p_vehicleID As Int32) As Task(Of Boolean)

    Return Task.Factory.StartNew(Of Boolean)(
        Function()
            Dim tempVehicle As Koolsoft.MARS.BusinessObjects.Vehicle

            For Each tempVehicle In Vehicles
                If p_vehicleID = 0 Or p_vehicleID = tempVehicle.VehicleID Then
                    UpdateVehicleStats(tempVehicle)
                End If
            Next

            Return True
        End Function)

End Function

You can then call your function as you suggested:

Dim updateTask As Task(Of Boolean) = UpdateVehicleSummaries(0)

Later on you can await the task to complete when you need the result:

Dim result = Await updateTask

Upvotes: 11

Related Questions