2016-05-19 180 views
0

我在點擊登錄按鈕後顯示活動指示器,直到將用戶重定向到另一個頁面,以使他們瞭解一些進度正在進行。但點擊登錄按鈕後,活動指示燈沒有立即顯示,幾秒鐘後顯示,更新UI BeginInvokeOnMainThread不立即反映

爲什麼它是這樣的?爲了減少延遲只有我把活動的指標......

我的代碼:

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

回答

0

是否該方法必須異步無效?看起來主線程上的任何特定調度都不需要是異步的。試試看看它是否改變了一切。您也可以嘗試在Device.BeginInvokeOnMainThread行和loadingPanel.IsRunning ...行上設置斷點,以查看延遲發生的位置。

0

首先,loginButtonGesture_Tapped()事件處理程序由UI線程觸發,因此您不需要使用Device.BeginInvokeOnMainThread(),它已經在UI線程中。但是由於您在這裏使用了Device.BeginInvokeOnMainThread(),所以延遲的原因是因爲在Android上,BeginInvokeOnMainThread()中的代碼被添加到MainLooper的消息隊列中(您的代碼不會立即執行)並在UI線程計劃處理其消息。

詳細的答案可以Xamarin的文件中找到:

對於iOS:

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線程中指定的選擇器公開的指定對象中的代碼。 這對大多數影響UIKit或AppKit的操作都是必需的,因爲這些API中的任何一個都不是線程安全的。

代碼在主線程返回主循環處理事件時執行。

對於安卓

很多人總以爲上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(action)執行。它被添加到Looper的消息隊列中,並在UI線程計劃處理其消息時進行處理。