簡體   English   中英

Xamarin HttpClient卡住並且不返回控制

[英]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;
        }
    }

使用.NetStandard; 請幫忙! 我不明白僵局發生在哪里 在此處輸入圖片說明

非事件處理程序上的async void意味着您的即發即忘呼叫將無法捕獲可能引發的任何異常。

參考Async / Await-異步編程最佳實踐

通過使用事件處理程序解決此問題

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM