Sliverlight for Windows Phone 非同步一種解決方案

來源:互聯網
上載者:User

在 Windows Phone 中非同步作業比較常見,我的方法很簡單,兩句話。這是第二句,它看上去是這樣的:

MethodCall.Invoke(() =>    // 這是一個Func<Object>,返回一個結果{        // 這是一個耗時1秒以上的操作,為了獲得一個值,亦或是一個結果集,我寫這個類的目的是我把http請求改寫成了同步,所以這樣會很方便,同樣這個類不僅限於http請求。所有耗時、延時操作都可用。        string result = BigFunction(); // List<string> results = BigFunction();
        return result;},(obj) =>    // 這是一個Action<Object>,處理返回結果{        // 獲得了返回結果,這裡是安全執行緒的,內部使用 Dispatcher.BeginInvoke 來調用        MessageBox.Show(obj.ToString());     // List<string> results = (List<string>)obj;});

另附上 MethodCall.cs

using System;using System.Threading;public static class MethodCall{    static MethodCall()     {        OnComplate += new ComplateCallBack((obj) => {            System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => {                _callBack.Invoke(obj);            });        });    }    private static event ComplateCallBack OnComplate;    private delegate void ComplateCallBack(object result);    private static Action<object> _callBack;    public static void Invoke(Func<object> action, Action<object> callback)    {        _callBack = callback;        ThreadStart t = new ThreadStart(() => {            OnComplate(action.Invoke());        });        new Thread(t).Start();    }}

用例說明(2011-11-15 11:50 新增):

因為wp7中只有非同步請求,如果想封裝一個架構實現某些功能,而架構內需要用到http請求,我只能把它寫成同步的,使用線程等待的機制實現了一個擴充方法:

 

    public static class WebRequestExt
{
const int DefaultTimeout = 2 * 60 * 1000; // 2 minutes timeout

public static Stream GetRequestStream(this WebRequest request)
{
using (AutoResetEvent done = new AutoResetEvent(false))
{
RequestState state = new RequestState();
state.request = (HttpWebRequest)request;

request.BeginGetRequestStream((ar) =>
{
RequestState rstate = (RequestState)ar.AsyncState;
rstate.streamResponse = rstate.request.EndGetRequestStream(ar);
done.Set();
}, state);
done.WaitOne(DefaultTimeout);
return state.streamResponse;
}
}

public static HttpWebResponse GetResponse(this WebRequest request, ref string errText)
{
using (AutoResetEvent done = new AutoResetEvent(false))
{
RequestState state = new RequestState();
state.request = (HttpWebRequest)request;
request.BeginGetResponse((ar) =>
{
RequestState rstate = (RequestState)ar.AsyncState;
HttpWebRequest rrequest = state.request;
try
{
rstate.response = (HttpWebResponse)request.EndGetResponse(ar);
Stream responseStream = state.response.GetResponseStream();
rstate.streamResponse = responseStream;
}
catch (Exception e)
{
rstate.exception = e;
}
done.Set();
}, state);
done.WaitOne(DefaultTimeout);
if (state.exception != null)
{
errText = state.exception.Message;
}
return state.response;
}
}
}

internal class RequestState
{
// This class stores the State of the request.
public HttpWebRequest request;
public HttpWebResponse response;
public Stream streamResponse;
public Exception exception;
public RequestState()
{
request = null;
streamResponse = null;
}
}

我在使用的時候就可以像這樣

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.baidu.com/");
string errText = null;

// 這裡直接獲得百度首頁的html
HttpWebResponse response = request.GetResponse(ref errText);
// 這樣的同步方式,而不是使用begin,end模式,再到callback方法中去處理
// IAsyncResult result = request.BeginGetResponse(RequestCallBack, state);


基於這個方法,可以寫出同步的http請求,那麼我在用的時候每次都去new線程不是很方便,所以封裝了這個方法,其實就是省去了一些代碼而已,用的時候可以這樣:

MethodCall.Invoke(
() =>
{
/*
* 實際上這段代碼是在新線程裡執行的,比如在Click事件裡直接這樣寫,也不會阻塞線程
*/

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.baidu.com/");
string errText = null;
// 同步調用GetResponse方法
HttpWebResponse response = request.GetResponse(ref errText);

using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
// 返回http請求的結果
return sr.ReadToEnd();
}
},
(obj) =>
{
/*
* 這裡通過MethodCall在內部執行完上面的方法後調用的,obj參數為上面方法的傳回值
*/

// 那麼這裡就可以獲得百度首頁的html了
// 同樣如果上面返回的是一個List<string>或者其他的對象
// 也可以(List<string>)obj或者(xxx)obj來轉換,傳回值是你可以決定的
// 當然這也可以改寫為一個泛型版,類型轉換也不用了
string html = obj.ToString();
MessageBox.Show(html);
});


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.