我有一个项目试图在构造函数中填充一些数据:
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对此项目无效
async
当然,如果我包装一个标准方法并从构造函数中调用它:
public async void Foo() { Data = await GetDataTask(); }
它工作正常。同样地,如果我使用旧的由内而外的方式
GetData().ContinueWith(t => Data = t.Result);
那也行。我只是想知道为什么我们不能await直接在构造函数中调用。可能有很多(甚至很明显)极端的情况和反对的理由,我只是想不到。我也在四处寻找解释,但似乎找不到任何解释。
await
构造函数的行为与返回构造类型的方法非常相似。而且asyncmethod不能返回任何类型,它必须是“ fire and忘记” void或Task。
void
Task
我认为,如果类型的构造函数T实际返回了Task<T>,那将非常令人困惑。
T
Task<T>
如果异步构造函数的行为与方法相同,则将async void破坏构造函数的含义。构造函数返回后,您应该获得一个完全初始化的对象。不是将来会在某个不确定的位置正确初始化的对象。也就是说,如果您很幸运并且异步初始化不会失败。
async void
所有这些只是一个猜测。但是在我看来,异步构造函数的可能性带来的麻烦多于其价值。
如果您确实想要方法的“即弃即用”语义async void(如果可能,应避免使用),则可以轻松地将所有代码封装在async void方法中,并从构造函数中调用它,如您在问题中提到的那样。