C# 构造函数中类字段的长时间运行初始化

C# 构造函数中类字段的长时间运行初始化,c#,asynchronous,constructor,synchronous,C#,Asynchronous,Constructor,Synchronous,假设我有下面的班级 public class MyClass { private readonly NinjaObject _myNinja; MyClass(NinjaFactory ninjaFactory) { _myNinja = ninjaFactory.CreateNinjaButItTakesTime(); } public void NinjaAttack() { _myNinja.Attack(); }

假设我有下面的班级

public class MyClass {
    private readonly NinjaObject _myNinja;

    MyClass(NinjaFactory ninjaFactory) {
        _myNinja = ninjaFactory.CreateNinjaButItTakesTime();
    }

    public void NinjaAttack() {
        _myNinja.Attack();
    }
}
现在,构造函数应该尽一切努力初始化该类,并使其准备好供应用程序使用,即创建忍者,并在调用时使其准备好攻击。让构造函数快速执行操作也是一个好主意。然而,如果创造忍者的过程需要很长时间,这可能是不可能的。我假设您可以通过某种静态工厂方法异步创建Ninja,但是当应用程序调用Ninja时,您可能(至少在理论上)没有准备好(即空对象)进行攻击

当您有一个类的字段,这些字段对该类的操作方式至关重要,但可能需要很长时间来构造时,在创建它们时采用的最佳模式是什么?在构造函数中保持同步,还是应用某种异步模式

我假设您可以通过某种静态工厂方法异步创建Ninja,但是当应用程序调用Ninja时,您可能(至少在理论上)没有准备好(即空对象)进行攻击

这就是异步静态工厂方法的用武之地:

public class MyClass
{
    private readonly Ninja ninja;

    private MyClass(Ninja ninja)
    {
        this.ninja = ninja;
    }

    public static async Task<MyClass> Create()
    {
        // Or however you create a ninja - ideally properly asynchronous
        var ninja = await Ninja.Create();
        return new MyClass(ninja);
    }

    public void NinjaAttack() => ninja.Attack();
}

根据您的上下文,您可能希望使用
await-ninjaTask.ConfigureAwait(false)

如果您提供有效的代码而不是伪代码,这将非常有帮助-因此
MyClass
而不是
构造函数
@JonSkeet-woops!更新。
public class MyClass
{
    private readonly Task<Ninja> ninjaTask;

    public MyClass(Task<Ninja> ninjaTask)
    {
        this.ninjaTask = ninjaTask;
    }

    public void NinjaAttack() => ninjaTask.Result.Attack();
}
public class MyClass
{
    private readonly Task<Ninja> ninjaTask;

    public MyClass(Task<Ninja> ninjaTask)
    {
        this.ninjaTask = ninjaTask;
    }

    public async Task NinjaAttack() => (await ninjaTask).Attack();
}