Cela faisait bien longtemps que je n’avais publié de billet.
Depuis quelques mois je bosse sur Windows 8 et là je suis ammené à faire des applications pour Windows Phone 8 / 7.5.
Je me suis dit : “Ce serait quand même dommage de ne pas réutiliser du code métier pour l’application Windows Phone”.
En effet, ce serait dommage car la “Portable Class Library” est là pour ça !
Ce qui m’intéressait c’était surtout de récuperer la couche d’accès aux services. J’avais développé cette couche avec async / await / HttpClient, qui ne sont pas supportés dans la “Portable Class Library”
. Du coup, j’ai refait au propre ma library (j’en ai profité pour virer le spécifique WinRT).
Ca y est ça compile ! Je run sur Windows 8 : ça passe !
Passons sur Windows Phone 8.
J’ajoute ma référence à mon projet WP8, ça compile, mais là pas moyen d’avoir mes données ! Analysons :
Dans ma “Portable Class Library” :
private static ManualResetEvent allDone = new ManualResetEvent(false);
public string GetFlux(string url) { HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Accept = "application/json"; req.Method = "GET"; // Création de l'objet état RequestState rs = new RequestState(); //On ajoute la requete dans l'objet état pour pouvoir le récupérer dans la callback rs.MyHttpWebRequest = req; //Appel asynchrone IAsyncResult response = req.BeginGetResponse(result => { //Récupération de l'objet etat RequestState state = (RequestState)result.AsyncState; //Récupération de la requete web (object HttpWebRequest) HttpWebRequest request = rs.MyHttpWebRequest; //Récupération de la réponse Web HttpWebResponse resp = (HttpWebResponse)request.EndGetResponse(result); Stream responseStream = resp.GetResponseStream(); StreamReader sr = new StreamReader(responseStream, Encoding.UTF8); _reponseContent = sr.ReadToEnd(); responseStream.Dispose(); allDone.Set(); }, rs); allDone.WaitOne(); return this._reponseContent; }
Sur Windows 8 :
string content = (newService()).GetFlux("http://monservice.com/get/users");
Aucun problème, on peut même binder le content
Sur Windows Phone 8 :
Service svc = new Service(); ThreadPool.RunAsync( (source) => { string content = svc.GetFlux("http://monservice.com/get/users"); } );
Sur Windows 8, les Thread sont bien Async. On passe bien dans la CallBack avant de sortir de GetFlux, ce qui n’est pas le cas sur Windows Phone !
Du coup il faut utiliser le ThreadPool.RunAsync (Merci Vincent Lepleux
)
Cool ! Maintenant on a de la donnée.
Allons un peu plus loin, je veux binder cette donnée. Avec le ThreadPool.RunAsync, je n’aurais pas accès à mon Thread UI !! C’est là qu’intervient notre ami le Dispatcher :
private void BindData(string content) { System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => { MyProperty = content; }); }
ThreadPool.RunAsync( (source) => { string content = svc.GetFlux("http://monservice.com/get/users"); BindData(content); } );
Et la boucle est bouclée !
Merci à Pierre Cauchois pour sa relecture
Les Techdays auront lieu les 08 09 & 10 Février au Palais des Congrès à Paris.