[英]Xamarin HttpClient stuck and does not return control
我不明白為什么主線程不回饋控制權來處理結果。
public partial class NewTravelPage : ContentPage
{
public NewTravelPage()
{
InitializeComponent();
}
protected async override void OnAppearing()
{
var locator = CrossGeolocator.Current;
var position = await locator.GetPositionAsync();
var vanues = await VenueLogic.getVenues(position.Latitude, position.Longitude);
venueListView.ItemsSource = vanues;
}
}
我將方法稱為getVenues:
public class VenueLogic
{
public async static Task<List<Venue>> getVenues(double latitude, double longitude)
{
List<Venue> vanues = new List<Venue>();
var url = VenueRoot.GenerateUrl(latitude, longitude);
using (HttpClient client = new HttpClient())
{
var res = await client.GetAsync("https://stackoverflow.com");
// here the code gives control to the main thread and stucks
var response = await res.Content.ReadAsStringAsync();
var venueRoot = JsonConvert.DeserializeObject<VenueRoot>
(response);
vanues = venueRoot.response.venues as List<Venue>;
}
return vanues;
}
}
非事件處理程序上的async void
意味着您的即發即忘呼叫將無法捕獲可能引發的任何異常。
通過使用事件處理程序解決此問題
public partial class NewTravelPage : ContentPage {
public NewTravelPage() {
InitializeComponent();
appearing += onAppearing;
}
protected override void OnAppearing() {
appearing(this, EventArgs.Empty);
}
event EventHandler appearing = delegate { };
private async void onAppearing(object sender, EventArgs args) {
try {
var locator = CrossGeolocator.Current;
var position = await locator.GetPositionAsync();
var vanues = await VenueLogic.getVenues(position.Latitude, position.Longitude);
venueListView.ItemsSource = vanues;
} catch( Exception ex) {
//handler error (Log?)
}
}
}
這將有助於捕獲任何異常以識別任何問題。
接下來,引用您使用的HttpClient錯誤
public class VenueLogic {
static HttpClient client = new HttpClient();
public async static Task<List<Venue>> getVenues(double latitude, double longitude) {
var url = VenueRoot.GenerateUrl(latitude, longitude);
var response = await client.GetAsync(url);
var jsonContent = await response.Content.ReadAsStringAsync();
var venueRoot = JsonConvert.DeserializeObject<VenueRoot>(jsonContent);
List<Venue> vanues = venueRoot.response.venues as List<Venue>;
return vanues;
}
}
創建一個客戶端,並將其用於應用程序的整個生命周期。
最后,我建議您考慮使用依賴注入在需要的地方注入服務實例,而不要使用那些靜態助手。
參考顯式依賴原則
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.