问题描述
我在哪里,我想在一个构造函数来填充一些数据的Silverlight项目:
I have a Silverlight 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:
修改器异步
是无效的此项目
当然,如果我在包装的标准方法,并呼吁从构造:
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.
推荐答案
构造函数的作用非常相似返回构造类型的方法。和异步
方法不能仅返回任何类型的,它有可能是射后不理无效
或工作
。
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
实际返回任务&LT; T&GT;
,那将是非常混乱,我觉得
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.
如果你真的想在射后不理异步无效的语义
(这应该是可以避免的,如果可能的话)的方法,你可以很容易地封装所有的$ C $下,在异步无效
方法和调用,从你的构造,因为你在问题中提到。
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.
这篇关于构造函数可以被异步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!