2016-07-28 15 views
3

私はViewModelにスレッド関連の問題がありますが、スレッド関連のようですが、何がうまくいかないのか、私の "修正"がそれをどう修正しているのかは分かりません。MvvmCross ShowViewModelのロードシーケンス

私は、初期データを読み込むために非同期メソッドを呼び出す必要があるViewModelを持っています。 MvvmCrossが自動的に呼び出すInitメソッドから非同期メソッドを呼び出しています。何らかの理由で読み込みに失敗した場合は、エラー画面を表示したいが、Initで呼び出されたメソッドの中でShowViewModelを呼び出すと、期待どおりの結果が得られない。 ShowViewModelは正しく呼び出されますが、デバッガでこれを実行すると、元のViewModel/Viewのロードが完了する前にErrorViewModelが表示され、元のViewModelによって上書きされるためロードされますが表示されません。 MvxTraceログは、ないShowViewModelは、それが初期のViewModelに呼び出された直後にErrorViewModelで呼び出されていることを教え、だけ初期ビューショー

public async Task Init() 
{ 
    await LoadInitialDataAsync(); 
} 

protected async Task LoadInitialDataAsync() 
{ 
    var loadResult = await LoadSomeStuffAsync(); 
    if (loadResult.IsBadNews) 
    { 
     ShowViewModel<ErrorViewModel>(); 
     return; 
    } 
} 

はここでロードコードの簡易版ですErrorView。

これを「修正」するには2つのうちのいずれかを実行できます。

私はTask.RunでLoadInitialDataAsyncへの呼び出しラップすることができます。これらの変更のどちらかが生成

protected async Task LoadInitialDataAsync() 
{ 
    var loadResult = await LoadSomeStuffAsync(); 
    if (loadResult.IsBadNews) 
    { 
     await Task.Delay(1); 
     ShowViewModel<ErrorViewModel>(); 
     return; 
    } 
} 

:私は、内側ShowViewModel呼び出しの前にわずかな遅延を追加することができます

await Task.Run(async() => 
{ 
    await LoadInitialDataAsync(); 
}); 

かを、目的の結果 - 読み込み中にバッドなことが起こると、ErrorViewModelはそのビューを表示します。

問題は、この修正を信頼できません。なぜなら、わかりやすいことが分からないため、この修正がどれほど堅牢であるかわからないからです。それは、最も不都合な時に、将来、ある時点で再び破る任意のタイミングのようなものです。

誰かがMvvmCrossの内部構造を十分に理解していれば、私はそれを感謝します!

+0

おそらく、この問題を再現するレポ/サンプルを提供できますか?上記の簡略化されたバージョンを使用しても、この問題は発生しません。 – Plac3Hold3r

+0

「答え」の誰も理解できないような、同じ問題を抱えています。問題は、あなたのCOREプロジェクトであなたが待たなければならないタスクがあり、その待ちの間に "ローダー"を表示したいということですか?右?その解決策を見つけましたか? – Ph0b0x

答えて

3

Initのメソッドはほとんど行いません。 Initは、通常、ShowViewModel<TViewModel>()に渡されたナビゲーションパラメータのコピーに使用されます。 Startメソッドは、LoadInitialDataAsyncを呼び出すなど、ViewModelの起動を行うためのものです。詳細についてはApp Lifecycle documentationをご覧ください。https://github.com/MvvmCross/MvvmCross/wiki/viewmodel--to-viewmodel-navigationに基づいて

+0

ありがとうございます。しかし、私はInit()の代わりにStart()を使用しようとしており、動作はまったく同じです。 –

0

あなたのアプリがViewModelにページを表示され、FirstViewModelを言う、そして 最初のページには表示が 新しいのViewModelページに前方に移動していることを要求することができ、使用してSecondViewModelを言います呼び出しのように:

ShowViewModel<SecondViewModel>(); 

はFirstViewModelはこの要求を行うと、その後、MvvmCross フレームワークは以下となります。

  • アプリ内SecondViewModelための「ページ」として使用するビューを見つけて - 通常、これは
  • SecondViewModel作成し、新しいのためのDataContextとしてそれを提供し、このSecondViewの新しいインスタンスを作成しますSecondViewなりますSecondView
  • 初期ビューhasntはまだ示されているが、ISSであるかもしれない、あなたのためのShowViewModel<ErrorViewModel()を呼び出さSecondView

を表示するには、オペレーティング・システムを依頼あなたのデバッガの動作に合うでしょう。

遅延は、表示に時間がかかる可能性があり、非同期タスクがブロックしないため表示され、表示が終了して別のビューに切り替わります。

私はその経験がありませんが、1つのオプションはおそらく前に初期化を行い、ShowViewModelでデータを渡すでしょう。 エラー状態を保存し、ビューをロードしてビューからビューモデルを呼び出して、作成後に切り替えることができます。

私は実際にそれらのどちらかのファンではありませんが、なぜ私はサービスを介して初期化を行い、新しいビューモデルに切り替える前に反応しないのでしょうか。

あなたの現在の構造がどのくらい複雑で、何がうまくいくのでしょうか。

関連する問題