user4103496
user4103496

Reputation:

VB.Net Async using Await properly

I'm using VB.Net, MVC 5, Visual Studio 2013. I have a question here on code review, in which it was suggested I make some of my view model functions asynchronous. I am trying to implement this suggestion.

I have a method in my view model which is called by an action (this portion seems to be working well):

Async Function getItemHistory(itemID As Integer, itemTypeID As Integer) As Threading.Tasks.Task(Of ItemHistoryPresentationModel)
    Dim returnModel = New ItemHistoryPresentationModel

    Dim getOperatorsTask As Task(Of List(Of String)) = getOperatorsAsync(itemID)
    Dim getItemNameTask As Task(Of String) = getItemNameAsync(itemTypeID)

    Await Task.WhenAll(getOperatorsTask, getItemNameTask)

    returnModel.ItemTypeString = getItemNameTask.Result
    returnModel.Operators = getOperatorsTask.Result

    Return returnModel
End Function

The problem I'm encountering is in my getItemNameAsync and getOperatorsAsync:

Async Function getItemNameAsync(itemTypeID As Integer) As Task(Of String)
    Dim itemName = (From row In db.tblCategories
                    Where row.Item_Type_Identifier = itemTypeID
                    Select row.Item_Type).SingleOrDefault()

    Return itemName
End Function

This function gives me a warning:

This async method lacks 'Await' operators and so will run synchronously. Consider using the 'Await' operator to await non-blocking API calls, or 'Await Task.Run(...)' to do CPU-bound work on a background thread.

I was under the impression that the Await in getItemHistory would take care of this issue for me.

What is the proper way to get rid of this warning?

Upvotes: 0

Views: 3061

Answers (1)

Scott Chamberlain
Scott Chamberlain

Reputation: 127543

You need to either make getItemNameAsync not marked as async and just have it be synchronous (but this will require you to change getItemHistory) or if you are using Enity Framework you need to use it's extension method SingleOrDefaultAsync to make it return a task.

Async Function getItemNameAsync(itemTypeID As Integer) As Task(Of String)
    Dim itemName = Await (From row In db.tblCategories
                    Where row.Item_Type_Identifier = itemTypeID
                    Select row.Item_Type).SingleOrDefaultAsync()

    Return itemName
End Function

You could also make it not Async and just return the task directly.

Function getItemNameAsync(itemTypeID As Integer) As Task(Of String)
    Dim itemNameTask = (From row In db.tblCategories
                    Where row.Item_Type_Identifier = itemTypeID
                    Select row.Item_Type).SingleOrDefaultAsync()

    Return itemNameTask 
End Function

Upvotes: 2

Related Questions