コンストラクターにデータを入力しようとしているプロジェクトがあります。
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
。おそらく、それに反するエッジケースや理由がたくさんあると思いますが、私には思いつきません。説明を探してみましたが、何も見つからないようです。
ベストアンサー1
非同期コンストラクターを作成することはできないため、プライベート コンストラクターによって作成されたクラス インスタンスを返す静的非同期メソッドを使用します。これはエレガントではありませんが、問題なく動作します。
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;
}
}