Sliverlight for Windows Phone 异步的一种解决方案

在 Windows Phone 中异步操作比较常见,我的方法很简单,两句话。这是第二句,它看上去是这样的:

MethodCall.Invoke(
() =>    // 这是一个Func<Object>,返回一个结果
{
        // 这是一个耗时1秒以上的操作,为了获得一个值,亦或是一个结果集,我写这个类的目的是我把http请求改写成了同步,所以这样会很方便,同样这个类不仅限于http请求。所有耗时、延时操作都可用。
        stringresult = BigFunction(); // List<string> results = BigFunction();
        returnresult;
},
(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
{
    staticMethodCall()
    {
        OnComplate +=new ComplateCallBack((obj) => {
            System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => {
                _callBack.Invoke(obj);
            });
        });
    }
    privatestatic eventComplateCallBack OnComplate;
    privatedelegate voidComplateCallBack(objectresult);
 
    privatestatic Action<object> _callBack;
    publicstatic voidInvoke(Func<object> action, Action<object> callback)
    {
        _callBack = callback;
        ThreadStart t =new ThreadStart(() => {
            OnComplate(action.Invoke());
        });
        newThread(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);
});


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值