8

ViewModelのコンストラクターにデータをロードしたいのですが、WinRTの非同期性のため、非同期メソッドを使用せざるを得ません。残念ながら、非同期コンストラクターを使用できないため、非同期メソッドを同期メソッドとして使用しようとしています。アプリケーションのロード時にデータをロード(非同期)するためのはるかに優れた方法があると確信していますが、現時点では私の心は空白を描いています。

私は自分の考えを使ってアプリを修正する方法を探しているか、より適切な方法を使ってこれを恒久的に修正する方法を探しています。

私が直面している問題を示すためだけに、コードは非常に単純です(ViewModelがない場合でも)。

public sealed partial class MainPage : Page
{

    public string Data { get; set; }

    public DataService _dataService { get; set; }

    public MainPage()
    {
        this.InitializeComponent();

        _dataService = new DataService();
        var t = _dataService.GetData();

        Data = t.Result;
    }

    /// <summary>
    /// Invoked when this page is about to be displayed in a Frame.
    /// </summary>
    /// <param name="e">Event data that describes how this page was reached.  The Parameter
    /// property is typically used to configure the page.</param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }


}

public class DataService
{
    public async Task<string> GetData()
    {
        //Force async
        await Task.Delay(1);

        return "Hello";
    }
}

敬具

4

2 に答える 2

9

asyncin constructorsに関する最近のブログ投稿を書きました。

要するに、私はasyncファクトリメソッドを好みます:

public sealed class MyViewModel : INotifyPropertyChanged
{
  private readonly DataService _service;

  private MyViewModel(DataService service)
  {
    _service = service;
  }

  private async Task InitializeAsync()
  {
    var result = await _service.GetData(); // async initialization

    Data = result; // update data-bound properties with the results
  }

  // Data triggers INotifyPropertyChanged on write
  public string Data { get { ... } set { ... } }

  public static async Task<MyViewModel> CreateAsync()
  {
    var ret = new MyViewModel();
    await ret.InitializeAsync();
    return ret;
  }
}
于 2013-01-22T00:08:13.977 に答える
2

非同期メソッドを強制的に同期的に実行すると、通常はデッドロックが発生するため、お勧めしません。ビュー モデルは通常、INotifyPropertyChanged PropertyChangedイベントを通じて変更通知をサポートするため、すべてのデータをすぐに利用できるようにする必要はありません。実際、データがハードコーディングされていない場合は、データがすぐに表示されるとは思わないでください。データの読み込み中に進行状況インジケーターを表示する必要がある可能性が高くなります。したがって...

コンストラクターで、結果を待たずに非同期初期化メソッドを呼び出し (コンストラクターで待機できないため)、すべてのデータが利用可能な場合の初期化メソッドで、ビューがバインドするプロパティ/プロパティに割り当て、PropertyChanged イベントを発生させますこれらのプロパティを変更し、可視性を制御するビュー モデル プロパティを変更して進行状況インジケーターを非表示にします。

于 2013-01-22T00:17:09.557 に答える