Home > Back-end >  Calling async function from a synchronous function causing x.result to hang ... fix it with extensio
Calling async function from a synchronous function causing x.result to hang ... fix it with extensio

Time:08-26

Take this async function:

Public Async Function MyAsyncFunction() As Task(Of String)
    Return Await SomeFunctionThatReturnsAString()
End Function

If I call it from a synchronous function like this:

Public Function MySyncFunction() As String
    Return MyAsyncFunction.Result
End Function

... the function hangs.

I wondered if it is possible to write an extension like this (the extension below does not work):

Public Module TaskExtensions

    <Extension()>
    Public Function SyncronousResult(Of T)(aTask As Task(Of T)) As T
        Dim result As T = Nothing
        Task.Run(Sub()
                     result = aTask.Result
                 End Sub).Wait()
        Return result
    End Function

End Module

... so I could call it like this:

Public Function MySyncFunction() As String
    Return MyAsyncFunction.SyncronousResult
End Function

?

CodePudding user response:

The ideal solution is not to block on asynchronous code (as I explain on my blog).

But, if you're in a situation where you literally can't use Await (for some reason), then you can try using one of the techniques in my Brownfield Async article. Note that there is no general-purpose solution that works everywhere.

The one you suggest is blocking for the result in a thread pool thread, which may or may not work. In the example code you posted, it wouldn't work because MyAsyncFunction has already captured the UI context and will attempt to resume in that context.

What you can try is call MyAsyncFunction from inside a delegate passed to Task.Run and then call GetAwaiter().GetResult() on the returned task. That works in most cases. In my article I refer to this as the "Thread Pool Hack".

  • Related