2016-05-19 30 views
0

ログインボタンをクリックして別のページにリダイレクトするまでアクティビティインジケータが表示され、進行状況がわかります。しかし、ログインボタンをクリックした後すぐにアクティビティインジケータが表示されず、数秒後に表示されます。UIを更新するBeginInvokeOnMainThreadが直ちに反映されない

なぜそうですか?その遅延を低減するためにのみ、私は...

マイコードアクティビティインジケータを入れています:

async void loginButtonGesture_Tapped(object sender, EventArgs e) 
{ 
    Device.BeginInvokeOnMainThread(() => 
        { 
         loadingPanel.IsRunning = true; 
         loadingPanel.IsVisible = true; 
        }); 
} 

答えて

0

方法は、非同期無効とする必要がありますか?この特定のスケジューリングのように、メインスレッド上のものは非同期である必要はありません。それが何か変わるかどうか調べてみてください。また、Device.BeginInvokeOnMainThread行と、delayPanel.IsRunning ...行にブレークポイントを設定して、遅延の発生場所を確認することもできます。

0

まず、loginButtonGesture_Tapped()イベントハンドラはUIスレッドによってトリガされるため、Device.BeginInvokeOnMainThread()を使用する必要はありません。すでにUIスレッド内にあります。しかし、ここでDevice.BeginInvokeOnMainThread()を使用して以来、遅延の理由は、AndroidではBeginInvokeOnMainThread()内のコードがMainLooperのメッセージキューに追加され(コードはすぐに実行されません)、UIスレッドそのメッセージを処理する予定です。 iOS用

はXamarinのドキュメントで見つけることができる詳細な回答

IOSPlatformServices.BeginInvokeOnMainThreadは()メソッドは、単にNSRunLoop.Main.BeginInvokeOnMainThread

public void BeginInvokeOnMainThread(Action action) 
{ 
    NSRunLoop.Main.BeginInvokeOnMainThread(action.Invoke); 
} 

https://developer.xamarin.com/api/member/Foundation.NSObject.BeginInvokeOnMainThread/p/ObjCRuntime.Selector/Foundation.NSObject/

を呼び出します

スレッドからこのメソッドを使用して、UIスレッドで指定されたセレクタで公開されている指定されたオブジェクトのコードを呼び出します。 これは、どちらのAPIもスレッドセーフではないため、UIKitまたはAppKitに影響するほとんどの操作に必要です。

メインスレッドがイベントを処理するためにメインループに戻るときにコードが実行されます。 Android用

多くの人がXamarin.Android BeginInvokeOnMainThread()メソッドを使用Activity.runOnUiThread()上だと思うが、これはそうではない、とrunOnUiThread()およびハンドラを使用しての間に差があります.Post():

public final void runOnUiThread(Runnable action) { 
    if (Thread.currentThread() != mUiThread) { 
     mHandler.post(action);//<-- post message delays action until UI thread is scheduled to handle messages 
    } else { 
     action.run();//<--action is executed immediately if current running thread is UI thread. 
    } 
} 

Xamarin.Android BeginInvokeOnMainThread()メソッドの実際の実装はAndroidPlatformServices.csクラスで

public void BeginInvokeOnMainThread(Action action) 
{ 
    if (s_handler == null || s_handler.Looper != Looper.MainLooper) 
    { 
     s_handler = new Handler(Looper.MainLooper); 
    } 

    s_handler.Post(action); 
} 
を見出すことができます

https://developer.android.com/reference/android/os/Handler.html#post(java.lang.Runnable) ご覧のとおり、アクションコードはHandler.Post(アクション)によってすぐに実行されません。これは、ルーパーのメッセージキューに追加され、UIスレッドがそのメッセージを処理するようにスケジュールされているときに処理されます。

関連する問題