EasyText, EasyLicense 的作者, https://github.com/EasyHelper Good Good Study,Day Day Up.

 

Silverlight_Rest_WCF系列之六:跨线程

跨线程有两种方法。

 1:this.Dispatcher.BeginInvoke

 2:SynchronizationContext

在上篇文章中我使用了第一种方法。显然每次都要调用this.Dispatcher.BeginInvoke是一件很“环照”的事情。

为了完善RestInvoke,我打算使用SynchronizationContext类,而SynchronizationContext类要和WebRequest关联。

为什么要和WebRequest关联呢?

因为一个Request对应了一个线程上下文,所以要保存请求时候的线程上下文,然后在成功获取数据后再调用保存的线程上下文来跨线程操作。

首先想到的是装饰模式,当然了,在这里可以用,但是从简单性角度考虑,就把Request和SynchronizationContext一起保存在HttpSyncWebRequest类中了。

/// <summary>
    
/// 同步HttpWebRequest
    
/// </summary>
    public class HttpSyncWebRequest
    {
        
public HttpWebRequest HttpWebRequest { getset; }
        
public SynchronizationContext SyncContext { getset; }
    }

代码很简单就是保存一个HttpWebRequest 和SyncContext对象。

在RestInvoke中,我们要修改GetWebRequest方法。代码如下:

/// <summary>
        
/// 获取WebRequest对象
        
/// </summary>
        
/// <param name="requestUriString">请求的地址</param>
        
/// <param name="httpMethod">请求的方法:GET,PUT,POST,DELETE</param>
        
/// <param name="contentType">请求的类型,json:"application/json"</param>
        
/// <returns></returns>
        public static HttpSyncWebRequest GetWebRequest(string requestUriString,
                                                    
string httpMethod,
                                                    
string contentType)
        {
            HttpWebRequest request 
= (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new Uri(requestUriString));
            request.Method 
= httpMethod;

            
if (!string.IsNullOrWhiteSpace(contentType))
            {
                request.ContentType 
= contentType;
            }

            
return new HttpSyncWebRequest() { HttpWebRequest = request, SyncContext = SynchronizationContext.Current };
        }

不是简单的返回HttpWebRequest对象,返回我们自定义的对象。

接着在每一个需要HttpWebRequest对象的地方使用

HttpSyncWebRequest syncWebRequest = GetWebRequest(requestUriString, httpMethod, "application/json;");

HttpWebRequest webRequest = syncWebRequest.HttpWebRequest;

 例如

 

View Code
 /// <summary>
        
/// 调用GET方法
        
/// </summary>
        
/// <typeparam name="T">结果的类型</typeparam>
        
/// <param name="requestUriString">请求的地址</param>
        
/// <param name="action">对结果的操作</param>
        public static void InvokeGet<T>(string requestUriString, Action<T> action)
        {
            
#region 添加时间戳,解决缓存问题

            
if (requestUriString.IndexOf("?"> 0)
            {
                requestUriString 
= requestUriString + "&" + DateTime.Now.ToString();
            }
            
else
            {
                requestUriString 
= requestUriString + "?" + DateTime.Now.ToString();
            }

            
#endregion

            HttpSyncWebRequest webRequest 
= GetWebRequest(requestUriString, "GET"string.Empty);
            
            webRequest.HttpWebRequest.BeginGetResponse((asyncResult) 
=>
            {
                SynchronizationContext currentContext
= asyncResult.AsyncState as SynchronizationContext;
                WebResponse response 
= webRequest.HttpWebRequest.EndGetResponse(asyncResult);
                HandleWebResponse(response, action,currentContext);
            }, webRequest.SyncContext);
        }

 

View Code
/// <summary>
        
/// 同步处理WebResponse
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="webResponse"></param>
        
/// <param name="action"></param>
        
/// <param name="currentContext"></param>
        private static void HandleWebResponse<T>(WebResponse webResponse, Action<T> action, SynchronizationContext currentContext)
        {
            
using (Stream responseStream = webResponse.GetResponseStream())
            {
                DataContractJsonSerializer serializer 
= new DataContractJsonSerializer(typeof(T));
                
if (typeof(T) == typeof(string))
                {
                    T responseObject 
= (T)(object)GetStringFromStream(responseStream);
                    currentContext.Post((callback) 
=>
                        {
                            action(responseObject);
                        }, 
null);
                }
                
else
                {
                    T responseObject 
= (T)serializer.ReadObject(responseStream);
                    currentContext.Post((callback) 
=>
                        {
                            action(responseObject);
                        },
null);
                }

            }
        }

 

posted @ 2011-05-16 19:49  LoveJenny  阅读(2118)  评论(11编辑  收藏  举报
EasyText, EasyLicense 的作者, https://github.com/EasyHelper Good Good Study,Day Day Up.