By Marty Neal


2011-11-16 01:19:48 8 Comments

I have a project where I'm trying to populate some data in a constructor:

public class ViewModel
{
    public ObservableCollection<TData> Data { get; set; }

    async public ViewModel()
    {
        Data = await GetDataTask();
    }

    public Task<ObservableCollection<TData>> GetDataTask()
    {
        Task<ObservableCollection<TData>> task;

        //Create a task which represents getting the data
        return task;
    }
}

Unfortunately, I'm getting an error:

The modifier async is not valid for this item

Of course, if I wrap in a standard method and call that from the constructor:

public async void Foo()
{
    Data = await GetDataTask();
}

it works fine. Likewise, if I use the old inside-out way

GetData().ContinueWith(t => Data = t.Result);

That works too. I was just wondering why we can't call await from within a constructor directly. There are probably lots of (even obvious) edge cases and reasons against it, I just can't think of any. I've also search around for an explanation, but can't seem to find any.

13 comments

@Harald Coppoolse 2015-07-17 08:56:00

Your problem is comparable to the creation of a file object and opening the file. In fact there are a lot of classes where you have to perform two steps before you can actually use the object: create + Initialize (often called something similar to Open).

The advantage of this is that the constructor can be lightweight. If desired, you can change some properties before actually initializing the object. When all properties are set, the Initialize/Open function is called to prepare the object to be used. This Initialize function can be async.

The disadvantage is that you have to trust the user of your class that he will call Initialize() before he uses any other function of your class. In fact if you want to make your class full proof (fool proof?) you have to check in every function that the Initialize() has been called.

The pattern to make this easier is to declare the constructor private and make a public static function that will construct the object and call Initialize() before returning the constructed object. This way you'll know that everyone who has access to the object has used the Initialize function.

The example shows a class that mimics your desired async constructor

public MyClass
{
    public static async Task<MyClass> CreateAsync(...)
    {
        MyClass x = new MyClass();
        await x.InitializeAsync(...)
        return x;
    }

    // make sure no one but the Create function can call the constructor:
    private MyClass(){}

    private async Task InitializeAsync(...)
    {
        // do the async things you wanted to do in your async constructor
    }

    public async Task<int> OtherFunctionAsync(int a, int b)
    {
        return await ... // return something useful
    }

Usage will be as follows:

public async Task<int> SomethingAsync()
{
    // Create and initialize a MyClass object
    MyClass myObject = await MyClass.CreateAsync(...);

    // use the created object:
    return await myObject.OtherFunctionAsync(4, 7);
}

@Malte R 2015-11-04 09:31:36

... But the return of an async method must be a Task? How do you get around that?

@Harald Coppoolse 2015-11-04 10:57:39

the ideas is not to use a constructor, but a static function that constructs the object ans async Initializes it. So don't do the initialization in the constructor, but in a separate private Initialize function, this Initialize function can return an awaitable Task and thus the static Create function can return an awaitable Task

@Malte R 2015-11-06 09:01:26

Nice, got it working. Thank you :)

@BrainSlugs83 2018-08-14 20:08:21

I'm referring to this as the async constructor pattern from now on. -- IMO, this should be the accepted answer, because it's nice, simple, and too the point -- Nice work!

@Seabizkit 2019-04-24 07:15:07

This was very helpful, thanks for sharing! and in enough detail to make it simple to understand. kudos

@Pierre Poliakoff 2012-09-20 20:39:23

Since it is not possible to make an async constructor, I use a static async method that returns a class instance created by a private constructor. This is not elegant but it works ok.

   public class ViewModel       
   {       
    public ObservableCollection<TData> Data { get; set; }       

    //static async method that behave like a constructor       
    async public static Task<ViewModel> BuildViewModelAsync()  
    {       
     ObservableCollection<TData> tmpData = await GetDataTask();  
     return new ViewModel(tmpData);
    }       

    // private constructor called by the async method
    private ViewModel(ObservableCollection<TData> Data)
    {
     this.Data=Data;   
    }
   }  

@Robert Oschler 2015-11-13 16:55:10

This answer should have much more votes in my opinion. It gives an answer that encapsulates and hides away the need to call an Initialize() method after an item is constructed, thus preventing the potential bug of constructing an object and forgetting to cal its initialize method.

@Damian Green 2015-12-04 11:17:57

Ag, this would be a great solution if you had control over the constructor but if your class implements an abstract base class, e.g. public class LoginModelValidator : AbstractValidator<Domain.Models.LoginModel> you have a problem

@DavidRR 2016-05-26 12:50:23

This approach uses a factory pattern. See another well-written similar answer here.

@Matt Thomas 2017-03-22 20:22:07

You don't always have control over callers, so a factory isn't always the general solution (to restate what Damian said in a more general way)

@Razvan Emil 2019-02-06 01:00:03

very nice solution @Pierre Poliakoff, love it

@johnsmith 2019-02-27 02:37:22

Some of the answers involve creating a new public method. Without doing this, use the Lazy<T> class:

public class ViewModel
{
    private Lazy<ObservableCollection<TData>> Data;

    async public ViewModel()
    {
        Data = new Lazy<ObservableCollection<TData>>(GetDataTask);
    }

    public ObservableCollection<TData> GetDataTask()
    {
        Task<ObservableCollection<TData>> task;

        //Create a task which represents getting the data
        return task.GetAwaiter().GetResult();
    }
}

To use Data, use Data.Value.

@user3053247 2019-02-05 06:51:59

This is a great place for a creation pattern. This is a lazy initialization. The constructor cannot be async, it needs to be atomic and have a concrete and state.

@Marty Neal 2019-02-06 16:24:28

Atomic is not the right word here. Atomic means that nothing can affect it while it's running. Other threads can definitely affect the constructor part way through. I don't know what you mean by "... have a concrete and state". Also other answers already suggest many different creation patterns to use.

@user3053247 2019-02-06 20:52:46

Nothing can affect it while the object constructed (not running as you said), and after the construction the object has a predicted state. Read more about atomic vs non-atomic.

@tsemer 2017-05-03 19:55:25

I was just wondering why we can't call await from within a constructor directly.

I believe the short answer is simply: Because the .Net team has not programmed this feature.

I believe with the right syntax this could be implemented and shouldn't be too confusing or error prone. I think Stephen Cleary's blog post and several other answers here have implicitly pointed out that there is no fundamental reason against it, and more than that - solved that lack with workarounds. The existence of these relatively simple workarounds is probably one of the reasons why this feature has not (yet) been implemented.

@Stephen Cleary 2017-05-04 15:05:50

@tomcat 2017-04-17 19:03:05

I would use something like this.

 public class MyViewModel
    {
            public MyDataTable Data { get; set; }
            public MyViewModel()
               {
                   loadData(() => GetData());
               }
               private async void loadData(Func<DataTable> load)
               {
                  try
                  {
                      MyDataTable = await Task.Run(load);
                  }
                  catch (Exception ex)
                  {
                       //log
                  }
               }
               private DataTable GetData()
               {
                    DataTable data;
                    // get data and return
                    return data;
               }
    }

This is as close to I can get for constructors.

@Andrew Barber 2012-11-07 21:58:35

That's about calling an async method from a constructor (which is possible, but probably not a good idea). This question is about the constructor itself being async (which won't compile at all).

@BrainSlugs83 2018-08-14 20:22:34

Many answers are saying "there's no reason it shouldn't be possible", this is a good reason -- also, if libraries start doing async stuff in their constructors (i.e. even .Wait() or .GetResult()) it can cause other issues; for example ASP.NET web forms requires special configuration for async calls to work (i.e. it's not a deadlock, but the execution context just drops off somewhere and never comes back -- even after configuration, it only works within certain parts of the page life cycle...) -- in general, I think hiding async calls in synchronous methods should be considered an anti-pattern.

@Dmitry Shechtman 2014-12-31 18:53:36

In this particular case, a viewModel is required to launch the task and notify the view upon its completion. An "async property", not an "async constructor", is in order.

I just released AsyncMVVM, which solves exactly this problem (among others). Should you use it, your ViewModel would become:

public class ViewModel : AsyncBindableBase
{
    public ObservableCollection<TData> Data
    {
        get { return Property.Get(GetDataAsync); }
    }

    private Task<ObservableCollection<TData>> GetDataAsync()
    {
        //Get the data asynchronously
    }
}

Strangely enough, Silverlight is supported. :)

@user1630939 2013-09-06 15:19:51

I use this easy trick.

public sealed partial class NamePage
{
  private readonly Task _initializingTask;

  public NamePage()
  {
    _initializingTask = Init();
  }

  private async Task Init()
  {
    /*
    Initialization that you need with await/async stuff allowed
    */
  }
}

@arame3333 2015-08-12 15:04:31

Worked for me, why wouldn't this work?

@Beachwalker 2016-02-03 07:56:53

Not finished when leaving constructor

@user618509 2019-10-30 14:12:28

your still not awaiting the return of the async so this is pointless

@Sanjay Patel 2013-03-20 08:55:35

you can use Action inside Constructor

 public class ViewModel
    {
        public ObservableCollection<TData> Data { get; set; }
       public ViewModel()
        {              
            new Action(async () =>
            {
                  Data = await GetDataTask();
            }).Invoke();
        }

        public Task<ObservableCollection<TData>> GetDataTask()
        {
            Task<ObservableCollection<TData>> task;
            //Create a task which represents getting the data
            return task;
        }
    }

@Stephen Cleary 2013-03-20 11:57:41

This creates and uses an async void method, which is not a good idea.

@Sanjay Patel 2013-03-20 13:09:05

so you have to use Data = GetDataTask().Result;

@Stephen Cleary 2013-03-20 13:33:59

No. Result could cause deadlocks. I have a variety of solutions described on my blog.

@svick 2011-11-16 01:49:40

Constructor acts very similarly to a method returning the constructed type. And async method can't return just any type, it has to be either “fire and forget” void, or Task.

If the constructor of type T actually returned Task<T>, that would be very confusing, I think.

If the async constructor behaved the same way as an async void method, that kind of breaks what constructor is meant to be. After constructor returns, you should get a fully initialized object. Not an object that will be actually properly initialized at some undefined point in the future. That is, if you're lucky and the async initialization doesn't fail.

All this is just a guess. But it seems to me that having the possibility of an async constructor brings more trouble than it's worth.

If you actually want the “fire and forget” semantics of async void methods (which should be avoided, if possible), you can easily encapsulate all the code in an async void method and call that from your constructor, as you mentioned in the question.

@Marty Neal 2011-11-16 03:01:37

I think this hits it closest. await can so often replace .ContinueWith that it was easy for me to forget that it's not so simple. I'm not even sure what I was thinking anymore, but I think I was thinking that await ought to "return" a constructed T (which you point out isn't what an async method can return) because that's was constructors "return" but then when await continues, the contructor doesn't return anything because its a constructor, like void. I'm not even making sense anymore, but your answer was the most helpful. Thanks.

@drowa 2014-11-02 03:04:38

"If the constructor of type T actually returned Task<T>, that would be very confusing, I think." I disagree. Like async Dispose, it would be very natural.

@BrainSlugs83 2018-08-14 20:11:15

The pattern proposed in this answer works for me.

@Brandon Moore 2011-11-16 01:29:29

I'm not familiar with the async keyword (is this specific to Silverlight or a new feature in the beta version of Visual Studio?), but I think I can give you an idea of why you can't do this.

If I do:

var o = new MyObject();
MessageBox(o.SomeProperty.ToString());

o may not be done initializing before the next line of code runs. An instantiation of your object cannot be assigned until your constructor is completed, and making the constructor asynchronous wouldn't change that so what would be the point? However, you could call an asynchronous method from your constructor and then your constructor could complete and you would get your instantiation while the async method is still doing whatever it needs to do to setup your object.

@Brandon Moore 2011-11-16 01:32:21

Moreover, what would it assign to o while it's waiting on the constructor to complete? I know the natural tendency is to think it should be null, but that's not how it works. You would never get null returned without threading... using threading doesn't change that.

@Emir Akaydın 2011-11-16 01:42:08

think about "var o;" only without "new MyObject()". that's what you get before constructor finishes its job. since making constructor async doesn't seem to be possible, we cannot test atomic times but we can assume it holds the same status with "var o;" only until it gets constructed.

@Brandon Moore 2011-11-16 01:56:42

'var o;' is not a valid statement. But let's assume we were specifying the type. In the first line you'd have 'object o;' and the second line would be 'o = new MyObject()'. Now, it HAS to assign something to o before it can go to the next line... there inlies the problem because it can't until the constructor is finished.

@BrainSlugs83 2018-08-14 20:23:53

it would return Task<MyObject>(), obviously.

@Emir Akaydın 2011-11-16 01:28:51

if you make constructor asynchronous, after creating an object, you may fall into problems like null values instead of instance objects. For instance;

MyClass instance = new MyClass();
instance.Foo(); // null exception here

That's why they don't allow this i guess.

@Brandon Moore 2011-11-16 02:01:18

You would think so, but that actually doesn't make sense even. If you make a call like 'var o = sqlcmd.BeginExecuteReader();' it's going to assign an IAsyncResult object to o before it continues to the next line. In your example, it can't assign anything to instance until the constructor is completed so it just doesn't make sense to allow the constructor to be asynchronous.

@Marty Neal 2011-11-16 02:36:05

The way I was expecting (hoping actually, "expect" is too strong a word) it to behave was to return the constructed object, but the object would finish constructing when what it was awaiting was ready. Since I think of await as being more of a set-up-a-continuation-and-then-return, I was hoping this might be possible. I wouldn't expect null to be returned.

@spender 2011-11-30 11:22:28

Allowing half constructed objects (as is implicit by an async constructor) would break other language constructs, such as the guarantees made by the readonly keyword.

@Ykok 2016-08-17 08:24:19

If the constructor of a class C was truly Async you would get a Task<C> that you would have to await.

Related Questions

Sponsored Content

15 Answered Questions

[SOLVED] Using async/await with a forEach loop

26 Answered Questions

[SOLVED] Why not inherit from List<T>?

9 Answered Questions

[SOLVED] Call one constructor from another

  • 2010-10-24 16:06:31
  • Avi
  • 431736 View
  • 924 Score
  • 9 Answer
  • Tags:   c# constructor

22 Answered Questions

[SOLVED] Can an abstract class have a constructor?

21 Answered Questions

[SOLVED] How and when to use ‘async’ and ‘await’

21 Answered Questions

[SOLVED] How do I call one constructor from another in Java?

  • 2008-11-12 20:10:19
  • ashokgelal
  • 805969 View
  • 2134 Score
  • 21 Answer
  • Tags:   java constructor

24 Answered Questions

[SOLVED] How would I run an async Task<T> method synchronously?

10 Answered Questions

[SOLVED] Calling the base constructor in C#

17 Answered Questions

[SOLVED] Virtual member call in a constructor

15 Answered Questions

[SOLVED] Can I call a constructor from another constructor (do constructor chaining) in C++?

  • 2008-11-21 09:43:08
  • Stormenet
  • 432636 View
  • 875 Score
  • 15 Answer
  • Tags:   c++ constructor

Sponsored Content