2017-01-08 11 views
0

このコードで何が問題になっているのか、あるいはどのようにXamarinの設定を変更してコードを正常に実行できるか教えてください。 Xam.Plugin.Connectivity.CrossConnectivityは:「デバイスはインターネットに接続されていますが、実現していればDownloadCountriesListAsync()がスタックしています(UWPは動作しません。アンドロイドは選択したインターネットパラメータをマニフェストでも使用しています)。このコードは、C#console appで動作しています。Xamarin.Forms with Net.Http

using System; 
using System.Collections.Generic; 
using System.Net.Http; 
using System.Threading.Tasks; 
using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 

namespace radacodeTestApp 
{ 
    public class ListsDownloader 
    { 
     public List<Country> Countries { get; private set; } 

     public ListsDownloader() 
     { 
      Countries = new List<Country>(); 
      var task = DownloadCountriesListAsync(); 
     } 

     public async Task<bool> DownloadCountriesListAsync() 
     { 
      try 
      { 
       var vkjsonResponse = await GetResponse(@"https://api.vk.com/api.php?oauth=1&method=database.getCountries&need_all=1&v=5.60"); 
       var jsonObject = JObject.Parse(vkjsonResponse); 
       foreach (var jO in jsonObject["response"]["items"]) 
        Countries.Add(JsonConvert.DeserializeObject<Country>(jO.ToString())); 

      } 
      catch (OperationCanceledException) 
      { 
       return false; 
      } 
      return true; 
     } 

     public async Task<string> GetResponse(string url) 
     { 
      using (var httpClient = new HttpClient()) 
       return await httpClient.GetStringAsync(url); 

     } 


    } 
    public class Country 
    { 
     public int Cid { get; set; } 
     public string Title { get; set; } 
     public override string ToString() 
     { 
      return Title; 
     } 
    } 
} 
+1

あなたはそうではありません、それが終了するのを待って、することはできません。コンストラクタでそれをしないでください。 – SLaks

+0

私はコンストラクタの仕上げを待っていません。もっと近くを参照してください –

+0

正確に;それは問題です – SLaks

答えて

0

バックグラウンドスレッドからDownloadCountriesListAsyncメソッドを呼び出します。あなたのコードは現在、メインスレッド(UIThreadとも呼ばれます)からDownloadCountriesListAsyncを呼び出すため、UIThreadがフリーズする可能性があります。

DownloadCountriesListAsyncメソッドをバックグラウンドスレッドから呼び出す方法を示すために、以下のコードを更新しました。

Async/Awaitはトリッキーな獣です。メソッドasyncをマークしても、自動的にバックグラウンドスレッドで実行されるわけではありません。非同期メソッドには、そのプロセスが完了するまでそのプロセスを親スレッドに渡す機能があることを意味します。 @Clanceyは、最新のXamarinカンファレンスでAsync/Awaitに関する素晴らしいプレゼンテーションを行いました。私は非常にそれをお勧めします!

https://www.youtube.com/watch?v=jgxJbshvCXQ

using System; 
using System.Collections.Generic; 
using System.Net.Http; 
using System.Threading.Tasks; 
using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 

namespace radacodeTestApp 
{ 
    public class ListsDownloader 
    { 
     public List<Country> Countries { get; private set; } 

     public ListsDownloader() 
     { 
      Countries = new List<Country>(); 
      Task.Run(async() => await DownloadCountriesListAsync()); 
     } 

     public async Task<bool> DownloadCountriesListAsync() 
     { 
      try 
      { 
       var vkjsonResponse = await GetResponse(@"https://api.vk.com/api.php?oauth=1&method=database.getCountries&need_all=1&v=5.60"); 
       var jsonObject = JObject.Parse(vkjsonResponse); 
       foreach (var jO in jsonObject["response"]["items"]) 
        Countries.Add(JsonConvert.DeserializeObject<Country>(jO.ToString())); 

      } 
      catch (OperationCanceledException) 
      { 
       return false; 
      } 
      return true; 
     } 

     public async Task<string> GetResponse(string url) 
     { 
      using (var httpClient = new HttpClient()) 
       return await httpClient.GetStringAsync(url); 
     } 
    } 

    public class Country 
    { 
     public int Cid { get; set; } 
     public string Title { get; set; } 
     public override string ToString() 
     { 
      return Title; 
     } 
    } 
} 
+1

ありがとう、Brandon –