Запустить асинхронную задачу без использования Await в вызываемом методе

Приложение Window Store с длительным методом, который мне нужно вызывать при запуске приложения, но мне не нужно ждать его завершения. Я хочу, чтобы он работал как фоновая задача. Если перейти на определенную часть приложения (отчетность), то я проверю и если надо подожду по задаче.

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

Это так называется

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

В нем нет вызова Await, и я получаю предупреждение о том, что он будет работать синхронно. Как мне запустить что-то подобное и запустить его асинхронно? Я хочу, чтобы он работал в своем собственном потоке/задаче, не блокируя поток интерфейса. Любые идеи?

Спасибо!


person Robert Beaubien    schedule 15.02.2013    source источник
comment
Простейшая реализация использует BackgroundWorker   -  person Dale M    schedule 15.02.2013
comment
Есть образцы? System.ComponentModel.BackgroundWorker не является частью платформы Windows.Store.   -  person Robert Beaubien    schedule 15.02.2013
comment
Нет достаточно коротких, чтобы поместить их здесь — я постараюсь составить краткий ответ ниже.   -  person Dale M    schedule 15.02.2013


Ответы (2)


Вы должны запустить код в своей функции внутри Task, который вы можете затем вернуть из него:

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

Затем вы можете вызвать свою функцию, как вы предложили:

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

Позже вы можете дождаться завершения задачи, когда вам понадобится результат:

Dim result = Await updateTask
person Damir Arh    schedule 15.02.2013
comment
Отлично, но я подозреваю, что вместо If Not updateTask.IsComplete должно быть Dim result = Await updateTask. Если он уже завершен, он должен немедленно вернуть результат, а если нет, он будет ждать завершения. - person Robert Beaubien; 15.02.2013
comment
@RobertBeaubien Да, ты прав. Я обновлю свой ответ соответственно. - person Damir Arh; 15.02.2013
comment
Я бы рекомендовал использовать Task.Run вместо Task.Factory.StartNew ; есть небольшие улучшения в Task.Run. - person Stephen Cleary; 16.02.2013

Я думаю, что это еще более простое решение, которое намного легче читать

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
person LorneCash    schedule 15.10.2013