2016-12-13 7 views
1

エラーが発生したときに2つのボタンを使用して警告ダイアログを表示したいとします。私の知る限り が、これはインタラクションプロパティを使用して、それを行う方法です:ReactiveUI - インタラクションハンドラでスケジューラを使用する

this.ViewModel.ConnectionError.RegisterHandler(interaction => 
{ 
    var retry = await this.DisplayAlert("Connection failed", "Do you want to retry?", "RETRY", "ABORT"); 
    if (retry) 
     interaction.SetOutput(DevicesViewModel.ErrorRecoveryOption.Retry); 
    else 
     interaction.SetOutput(DevicesViewModel.ErrorRecoveryOption.Abort); 
}); 

問題は、例外は、サードパーティのライブラリーにスレッド内でスローされるということです。 DisplayAlertは、メインスレッドで呼び出される必要があります。私は以下を試しました:

コンソールにログメッセージが表示されますが、ダイアログが表示されず、ReactiveUI.dll内でアプリケーションがクラッシュします。 私は何が間違っていますか?

答えて

1

クラッシュの詳細を調べると、何もその対話を処理しなかったと不平を言うことがわかります。これは、登録されたハンドラが同期しているためです。確かに、非同期作業を開始しますが、ReactiveUIには、その作業が完了するのを待つ手段がありません。

これは、お電話で解決されたRegisterHandlerのオーバーロードを確認することで確認できます。それはRegisterHandler(Action<InteractionContext<TInput, TOutput>>)です。言い換えれば、「対話をコンテキストを受け取り、同期的に処理ハンドラを登録

を何がやりたいことは、非同期RegisterHandlerのいずれかの方法で呼び出すです。

  • RegisterHandler(Func<InteractionContext<TInput, TOutput>, Task>)
  • RegisterHandler(Func<InteractionContext<TInput, TOutput>, IObservable<Unit>>)

ロジックを書くにはさまざまな方法がありますが、私は非同期を表現する手段としてRxを好む傾向がありますので、次のように記述してください:

this 
    .ViewModel 
    .ConnectionError 
    .RegisterHandler(
     context => 
      Observable 
       .Start(
        () => Unit.Default, 
        RxApp.MainThreadScheduler) 
       .SelectMany(_ => this.DisplayAlert("Connection failed", "Do you want to retry?", "RETRY", "ABORT")) 
       .Do(result => context.SetOutput(result ? ErrorRecoveryOption.Retry : ErrorRecoveryOption.Abort))); 

Observable.Startコールは正しいスレッドで私たちを入手するためのちょっとしたハックです。私があなただったらそれを掃除する方法を見ていきます。具体的には、正しいスレッドで対話を開始する方法を見ていきます。つまり、Handle(おそらくあなたのVM)がUIスレッドでそうするべきであれば何でも。正しいスレッドでコマンドを実行するのはあなたの責任ですが、Handleは同じです。

+0

あなたのように、私は非同期を表現するためにRx構文も好きですが、私はUnit observable trickが欠けていました。それでも決してありません。 Do文の後に.Select(_ => Unit.Default)を追加するか、アクションのオーバーロードを引き続き使用する必要があります。 それでもクラッシュしますが、例外があります。「無効なウィンドウハンドルです。このAPIは、CoreWindowを持つスレッドから呼び出されるか、ウィンドウが明示的に設定されている必要があります。に –

関連する問題