首页 > C# >  C#构造函数可以是异步的吗?

 C#构造函数可以是异步的吗?

上一篇 下一篇

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

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

不幸的是,我收到一个错误:

修饰符对此项目无效async

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

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

它工作正常。同样,如果我使用旧的由内而外的方式

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

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

分割线

网友回答:

由于无法创建异步构造函数,因此我使用静态异步方法返回由私有构造函数创建的类实例。这并不优雅,但工作正常。

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

分割线

网友回答:

构造函数的作用与返回构造类型的方法非常相似。并且方法不能返回任何类型,它必须是“即发即弃”,或者.asyncvoidTask

如果类型的构造函数实际上返回,那将非常令人困惑,我认为。TTask<T>

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

这一切都只是一个猜测。但在我看来,拥有异步构造函数的可能性会带来比它的价值更多的麻烦。

如果你真的想要方法的“即发即弃”语义(如果可能的话,应该避免),你可以轻松地将所有代码封装在一个方法中,并从你的构造函数调用它,正如你在问题中提到的。async voidasync void

分割线

网友回答:

您的问题相当于创建文件对象并打开文件。实际上,在实际使用该对象之前,您必须执行许多类的两个步骤:create + Initialize(通常称为类似于Open的东西)。

这样做的优点是构造函数可以是轻量级的。如果需要,可以在实际初始化对象之前更改某些属性。设置所有属性后,将调用 / 函数来准备要使用的对象。此函数可以是异步的。InitializeOpenInitialize

缺点是,在使用类的任何其他函数之前,您必须信任类的用户,该用户将调用该用户。事实上,如果你想让你的类完全证明(万无一失?),你必须签入每个被调用的函数。Initialize()Initialize()

使这更容易的模式是声明构造函数私有并创建一个公共静态函数,该函数将在返回构造对象之前构造对象并调用。这样,您就会知道有权访问该对象的每个人都使用了该函数。Initialize()Initialize

该示例演示了一个类,该类模拟所需的异步构造函数

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
    }

用法如下:

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

模板简介:该模板名称为【 C#构造函数可以是异步的吗?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 339次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 04-21
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
单页式简历模板 微信素材 响应式 微信公众平台 自适应 微信模板 微信图片 微信文章 企业网站 html5
您可能会喜欢的其他模板