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 {  get set ; }
        
public  SynchronizationContext SyncContext {  get set ; }
    }

代码很简单就是保存一个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 );
                }

            }
        }

 

你可能感兴趣的:(silverlight)