Soru & Cevap

Windows Phone Json Parse İşlemi Bekleme ...

11.04.2014 - 05:45

Basitçe bir request-response a dayalı bir class oluşturdum, istediğim kategorinin id sini girerek o kategorinin ilk yazısını json olarak okuyup parse edip getWriting ile başka classlarımda JsonDataManager objesi oluşturarak çekiyorum.Fakat problem şu ki Aync olmasına karşın hala JObject.Parse methodum json response umu beklemiyor ve direk ilk başta tanımladığım "doldurulacak" stringini alıyor. Beklemesini nasıl sağlayabilirim ? Teşekkürler

[code] 

public class JsonDataManager
    {
         String myData = "doldurulacak";

        public JsonDataManager(string Category)
        {
            String url = "http://www.kaanbarisbayrak.com/?json=get_category_posts&cat="+Category;
            WebClient wc = new WebClient();
            wc.Encoding = System.Text.Encoding.UTF8;
            wc.Headers["Accept"] = "application/json";
            wc.DownloadStringAsync(new Uri(url), UriKind.Relative);
            wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
            
        }

        public String getWriting()
        {
            JObject obj = JObject.Parse(myData);
            JArray array = (JArray)obj["posts"];
            string writing = (string)array[0]["content"]; 
            return writing;
        }


        private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            myData = e.Result;
        }

    }

[/code]

15 Görüntülenme

1 Cevap

Sitedeki sorulara cevap verebilmek için giriş yapın ya da üye olun.

picture-472-1375079047.jpg
mehmet.altiparmak
11.04.2014 - 09:03

Selam Kaan,

Beklediğin JSON response wc_DownloadStringCompleted methodu çağırılıdıktan sonra hazır olacak. O method'da asenktron bi şekilde gerçekleştirilen HTTP isteği tamamlandığında otomatik olarak çağırılacak DownloadStringCompleted eventi için handler olarak atadığın için. Tahmin ediyorum sen wc_DownloadStringCompleted methodu çağırılmadan dışarıdan getWriting methodunu çağırıyorsun. 

Bunu hem wc_DownloadStringCompleted hem de getWriting methodunun içerisine Break Point koyarak test edebilirsin. Debugger öncelikle wc_DownloadStringCompleted methoduna düşmeli. Aksi halde dediğin gibi myData değerinin default değeri işlenir. 

Bir methodun asenkron olması UI Thread üzerinde çalışan koda paralel olduğu anlamına gelir. Kod çalıştıran iki kanalın olduğunu düşünürsen sen bir kanaldan http isteği gönderiyorsun. Diğer kanaldan getWriting methodunu ancak bu ikisinin birbirinden haberi yok. 

Ne yapabilirsin? 

- Nuget ile projene "Microsoft Http Client Libraries" kütüphanesini ekledikten sonra. async-await anahtar kelimelerini destekleyen HttpClient sınıfını kullanabilirsin. Kullanımı çok daha rahattır, benim tavsiyem budur. Örnek

- JsonDataManager sınıfı içerisinde DataRequestCompleted isminde bir event tanımlar, bu event'i wc_DownloadStringCompleted methodunda fire edersin. getWriting methodunu ise DataRequestCompleted eventine atadığın handler'da çağırırsın. Tabi burada UI Thread senkronizasyonu etc yapman gerekecek eğer dönen veriyi bir UI komponentine set ediyorsan. 

Kaan Barış BAYRAK
13.04.2014 - 12:15
Uzun denemeler sonucunda birkaç yol denedim fakat hepsinde olduğu gibi bir stringi beklemesi için en son myData.Result; kullandığım anda bu satıra geliyor ve main thread blocklanıyor.Okuduğum kadarıyla main thread in içinde await kelimesi .Net 4.5 ile engellenmiş ve bunun yerine .Result kullanılmaya başlanmış (link) fakat dediğim gibi .Result ta direk takılıyor ve interfaceim de donuyor [code] public class JsonDataManager { Task myData; public JsonDataManager(string Category) { String url = "http://www.kaanbarisbayrak.com/?json=get_category_posts&cat="+Category; HttpClient hc = new HttpClient(); myData = hc.GetStringAsync(url); } public String getWriting() { // wait for the download task to finish string data = myData.Result; // use the resulting string JObject obj = JObject.Parse(data); JArray array = (JArray)obj["posts"]; string writing = (string)array[0]["content"]; return writing; } } [/code]
Mehmet Altıparmak
13.04.2014 - 09:38
GetWriting fonksiyonunu çağırırken de await kullanmalısın. string writing = await manager.getWriting();