2016-10-29 3 views
0

MVM 스타일 응용 프로그램이 Xamarin 양식에 설정되어 NavigationPage 내에서 자체 호스팅되는 ViewModel 첫 번째 방법을 통해 로그인 페이지를 표시합니다. 내가 사용하는 경우,내 ViewModel의 Rx 구독에서 PushAsync 탐색 요청을 실행하는 방법

public async Task PushAsync(INavigationPageModel page) 
{ 
    var view = _viewFactory.CreatePage(page); 
    await Navigation.PushAsync(view); 
} 

지금 :

var navigationController = Application.Current.MainPage as NavigationPage; 

if (navigationController != null) 
    return navigationController.Navigation; 

다음 나에게 이렇게 같은 PushAsync 방법에 대한 액세스를 제공합니다

는이 같은 올바른 탐색 속성을 설정 INavigationService 인스턴스를 주입 이 메서드는 명령 (예를 들어) 내보기 내비게이션 스택에 올바르게 밀어 넣은 볼 수 있습니다. 그러나 Rx를 사용하여 BehaviourSubject를 통해 응용 프로그램의 '연결됨'상태를 감시합니다.이 문제는 저에게 문제를 일으키는 것으로 보입니다.

오류가 발생하지 않지만보기 자체는 무엇입니까? 이 스택에 푸시되지만 나에게는 보이지 않습니다 (디버거의 스택에서 볼 수 있음). 나는 이것이 어떻게 든 UI ​​쓰레드와 관련이 있다고 가정 할 수 있지만 확실하지는 않다.

내 RX 구독이 비동기 메서드 호출을 지원해야하는 것처럼 보였으므로 몇 번의 반복 작업을 거쳤습니다. 현재는 다음과 같습니다

_application.ConnectionManager.State 
      .Where(s => s == ConnectionState.Connected) 
      .SelectMany(l => Observable.FromAsync(ChangePageAsync)) 
      .SubscribeOn(Scheduler.UiScheduler) 
      .Subscribe(); 

내 변경 페이지 방법은 다음과 같습니다

new SynchronizationContextScheduler(SynchronizationContext.Current); 
:이 같은 아이폰 OS 응용 프로그램에 대한 AppDelegate에의 UI 스케줄러를 캡처 완성도를 들어

private Task ChangePageAsync() 
{ 
    var viewModel = _viewModelFactory.CreateModel<DashboardPageViewModel>(); 
    return Navigation.PushAsync(viewModel); 
} 

내가 말했듯이 오류는 없지만 Rx 비동기 작업을 통해 새 페이지를 표시하지는 않습니다. 어떤 아이디어? 그게 날 미친 운전.

+0

동기화 컨텍스트 (UiScheduler 캡처 위치)를 캡처하는 데 사용되는 스레드가 실제로 기본 UI 스레드인지 확인하십시오. Scheduler 클래스가 싱글 톤 (보이는 것처럼)이고 UiScheduler가 느리게 캡처 된 경우 (즉, 속성이 처음 사용될 때) 먼저 백그라운드 스레드에서 액세스 할 수 있으므로 실제로 UI 스레드가 될 수 없습니다. 아, SelectMany에는 Task를 처리 할 수있는 오버로드가 있기 때문에 'Observable.FromAsync'내부가 필요하지 않습니다. – ibebbs

+0

@ibebbs 구독을 다른 스레드로 푸시하면 UI 스레드에 예외가 없다는 메시지가 표시되므로 동기화 컨텍스트 캡처가 올바르다 고 가정합니다. 내 캡처 접근법이 유효하다는 것을 확인하기 위해 다른 누군가를 기다리고 있습니다. 스케줄러는 주입 된 스케줄러의 속성이므로 싱글 톤이 아닙니다! –

+0

내 ChangePageAsync 메서드는 실제로 아무 것도 반환하지 않으므로 반환 유형을 수정하지 않으면 SelectMany에 대한 오버로드를 사용할 수 없다고 생각합니다.이것은 실제로 선택의 부작용입니다. 작동시키기위한 또 다른 시도입니다. 나는 가졌고 그것을 바꾸려고 노력했다. 아직도 기쁨이 없습니다. –

답변

1

오, 죄송합니다. 코드를 완전히 읽지 않았습니다. SubscribeOn이 아닌 ObserveOn을 사용하고 SelectMany 앞에 배치해야합니다. 이에 변경 : 이것은 페이지 변경을 시도 전에 UI 스레드 에의 보장

_application.ConnectionManager.State 
    .Where(s => s == ConnectionState.Connected) 
    .ObserveOn(Scheduler.UiScheduler) 
    .SelectMany(l => Observable.FromAsync(ChangePageAsync)) 
    .Subscribe(); 

. Subscription은 지정된 스케줄러 (일반적으로 구독이 차단 될 때 사용됨)에서 구독의 스캐 폴딩이 수행되는지 확인하는 데 사용됩니다.

+0

FUNK 켜기. 알았어! 전에 ObserveOn을 시도했지만, SelectMany 후에 항상 SubscribeOn을 사용했습니다. –

관련 문제