當我嘗試在ViewModel初始化期間加載API端點的內容時,Xamarin.Android/iOS上的MvvmCross出現問題。我正在從API中加載當前的天氣預報,並且我使用異步方法編寫了它,並從初始化生命週期回調中調用它。到目前爲止,我已經嘗試過Stat()和Init()。在這兩種情況下,我的UI用我的ViewModel中的值加載,但立即凍結。如果我在異步代碼中的任何位置設置斷點,斷點捕獲並通過播放,它按預期工作。我懷疑某處存在某種競爭條件,但我不確定如何避免它,並在顯示ViewModel/View時加載數據。下面的代碼我有:當初始化期間調用異步方法時,MvvmCross UI凍結
// WeatherService的
public async Task<WeatherStatus> GetWeatherStatus (string zip)
{
var client = new HttpClient();
var msg = await client.GetAsync(string.Format(WeatherApiUrlBase, WeatherApiKey, zip));
if (msg.IsSuccessStatusCode)
{
using (var stream = await msg.Content.ReadAsStreamAsync())
{
using (var streamReader = new StreamReader(stream))
{
var str = await streamReader.ReadToEndAsync();
var obj = JsonConvert.DeserializeObject<WeatherStatus>(str);
return obj;
}
}
}
return null;
}
// FirstViewModel
public async override void Start()
{
base.Start();
FetchWeatherStatus();
}
private async void FetchWeatherStatus() {
var weatherData = await _service.GetWeatherStatus ("84043");
FeelsLike = weatherData.current_observation.feelslike_f;
}
這異步代碼從按下按鈕MvxCommand就好工程;但如果從構造函數調用Init或Start,則每次都會凍結UI,如果我沒有某個斷點的話。如果有人能幫我找到我在做什麼錯,我會很感激。謝謝。
編輯
我發現應用程序似乎正常運行時,我不調試。我停止了Xamarin Studio的調試器並重新啓動應用程序,並且它運行完美。
如這裏要求是我的XML我使用綁定FeelsLike:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
local:MvxBind="Text FeelsLike" />
我也嘗試添加.ConfigureAwait(假);對我所有的等待電話,它似乎更糟。用戶界面永遠不會被初始化,而是坐在黑屏上,而不僅僅是我的常規UI被凍結。
這可能是有益的,但這裏是我的項目文件夾的鏈接(這是非常小的,因爲我剛學這個框架): http://goo.gl/SJscZA
EDIT 2
問題可能是在我HttpClient代碼?我用一個簡單的Task.Delay(5000)替換了它,並返回一個空的WeatherStatus來查看發生了什麼,並且它沒有凍結。我會研究以另一種方式獲取數據。我是Xamarin的新手,所以我願意接受這裏的建議。謝謝。這裏是我的Task.Delay()的代碼片段:
public async Task<WeatherStatus> GetWeatherStatus (string zip)
{
await Task.Delay (5000);
return new WeatherStatus();
}
我無法看到此代碼導致掛起的任何原因。根據你的描述,這聽起來像這是活動的OnCreate/OnStart/OnResume期間的競爭狀態。你可以編輯你的問題來顯示'FeelsLike'的UI綁定是什麼樣的? (我懷疑這會有所幫助 - 但我有希望!)作爲一種潛在的調試方法,您可以嘗試將跟蹤添加到VM方法和「OnXXX」覆蓋。對於解決方法,您可以使用'ConfigureAwait'將工作推出UI線程,或者您可以嘗試向VM添加'DelayedStart',並可以從'OnResume'調用它。 – Stuart