Search code examples
new-operatorvb.net-2010

Can we call await in constructor?


Shared Sub New()
    'Await setAllAccountsAsync()
    SetAllAccounts()
End Sub

This one works

However,

Shared Sub New()
    Await setAllAccountsAsync()
    'SetAllAccounts()
End Sub

doesn't

Shared async Sub New()
    Await setAllAccountsAsync()
    'SetAllAccounts()
End Sub

also doesn't work

However

Private Shared Async Sub SetAllAccounts()
    Await setAllAccountsAsync()
End Sub

works fine.

So we can return void in an async but we cannot do that in the constructor. Why? Is this true?

Note:

I do not want this to be a constructor actually. Noticed it's shared new rather than new. I just want some code to be run once. For example, in my case, the initializer would surf web and find all the trading pair and store the trading pairs in a private variable. I want that to be done before the class is used.

The content of setAllAccountsAsync is the following

Private Async Function initializeAsync() As Task
    _marketid = Await CookieAwareWebClient.downloadString1Async("https://www.coinexchange.io/api/v1/getmarkets")
End Function

Solution

  • Is this true?

    Yes.

    Why?

    Async Sub (or async void) methods were added to C# and VB so that event handlers could be asynchronous. You should avoid Async Sub in all other situations. Specifically, Async Sub is not a valid way to implement a constructor.

    Constructors cannot be asynchronous, and the language is likely to keep this principle for the foreseeable future. If you need to asynchronously construct an instance, you should use a factory method, i.e., a static method that returns Task(Of T) for whatever T your type is. More details and alternative approaches are described in my blog post on async constructors.