Windows Phone的異步模型

爲了不阻塞UI,在windows phone的多線程上完全去掉了同步的模型,全部使用異步模型來處理請求。
這樣帶來的好處是UI不會被卡死,能夠一直響應用戶的響應,將比較耗時的操作丟給後臺線程處理,並且能避開線程同步的麻煩。
但這樣一來,寫出來的代碼也比較難看,還可能涉及到數據共享的問題。
我相信如果你的應用涉及到HttpRequest的話那麼一定會遇到我說的情況。
歡迎大家一起討論你的思路。

以下是幾種我常用的異步請求代碼的模型
1、使用匿名函數,有時候爲了節約會使用lamda表達式
2、事件模式,通過訂閱請求完成事件
3、Async CTP

第一種方式的代碼如下:

private string Reqest()        {            string resultString = string.Empty;            HttpWebRequest request = HttpWebRequest.CreateHttp("http://www.google.com");            request.Method = "GET";            request.BeginGetResponse((IAsyncResult result) =>             {                HttpWebRequest webRequest = result.AsyncState as HttpWebRequest;                HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(result);                Stream streamResult = webResponse.GetResponseStream();                StreamReader reader = new StreamReader(streamResult);                //獲取的返回值                resultString = reader.ReadToEnd();            }, request);            return resultString;        }


第二種方式的代碼如下:

public delegate void GetResultEventHandler(object sender, string e);        public event GetResultEventHandler OnGetInfoCompleted;        private void Reqest()        {            HttpWebRequest request = HttpWebRequest.CreateHttp("http://www.google.com");            request.Method = "GET";            request.BeginGetResponse(GetInfoCompleted, request);        }        protected void GetInfoCompleted(IAsyncResult asyncResult)        {            try            {                HttpWebRequest webRequest = asyncResult.AsyncState as HttpWebRequest;                HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(asyncResult);                Stream streamResult = webResponse.GetResponseStream();                StreamReader reader = new StreamReader(streamResult);                //獲取的返回值                string resultString = reader.ReadToEnd();                if (OnGetInfoCompleted != null)                {                    OnGetInfoCompleted(this, resultString);                }            }            catch (WebException ex)            {                MessageBox.Show(ex.Message);            }        }


第三種方式的代碼實現如下:

private async resultString Reqest()        {            HttpWebRequest request = HttpWebRequest.CreateHttp("http://www.google.com");            request.Method = "GET";            HttpWebResponse webResponse = await request.GetResponseAsync();            Stream streamResult = response.GetResponseStream();            StreamReader reader = new StreamReader(streamResult, new GB2312.GB2312Encoding());            string resultString = reader.ReadToEnd();            return resultString;        }


因爲有時候請求會有嵌套關係,比如在請求第二個數據之前,需要先請求第一個數據,所以用第一種方式會一直匿名很多層,讓我覺得很不爽。
在沒有async CTP for windows phone之前,我一直用第二種方式來寫代碼,因爲這樣邏輯比較清楚。只是事件的模型看起來也不完美,但這也算是比較常用的異步模型,用事件來傳遞參數。缺點是當邏輯需要阻塞線程的時候,卻又阻塞不了。
我想這也是async框架出現的原因吧。
在windows8的開發中,async框架已成爲正式版,也就是說已經完全支持了第三種異步模型,也就是以async,await爲主導的模型。這樣即可以讓需要等待的代碼阻塞着,又可以讓UI線程保持通暢,並且代碼的邏輯也能很清楚,又避開了線程同步的數據鎖的麻煩。
算是在這件事情上現階段較爲完美的方案了。

拋磚引玉,大家積極來天翼論壇討論。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章