构造函数可以是异步的吗? [英] Can constructors be async?

查看:45
本文介绍了构造函数可以是异步的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个项目,我试图在构造函数中填充一些数据:

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:

修饰符 async 对此项无效

当然,如果我包装在标准方法中并从构造函数中调用它:

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);

这也行.我只是想知道为什么我们不能直接从构造函数中调用 await .可能有很多(甚至是明显的)边缘情况和反对它的理由,我只是想不出任何一个.我也四处寻找解释,但似乎找不到任何解释.

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.

推荐答案

构造函数的行为与返回构造类型的方法非常相似.而 async 方法不能只返回任何类型,它必须是触发后忘记"voidTask.

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.

如果 T 类型的构造函数实际上返回了 Task,我想那会很混乱.

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

如果异步构造函数的行为方式与 async void 方法相同,那么这种方法就破坏了构造函数的本意.构造函数返回后,您应该得到一个完全初始化的对象.不是在未来某个未定义点实际正确初始化的对象.也就是说,如果你很幸运并且异步初始化没有失败.

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.

如果您确实想要async void 方法的即发即弃"语义(应该尽可能避免),您可以轻松地将所有代码封装在async void 方法并从您的构造函数调用它,正如您在问题中提到的那样.

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.

这篇关于构造函数可以是异步的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆