zoukankan      html  css  js  c++  java
  • 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);
                    }

                }
            }
  • 相关阅读:
    openlayers之标注功能四:聚合标注
    openlayers加载百度地图作为底图坐标偏移的解决办法
    设置bootstrap按钮组选中状态
    openlayers F11全屏显示
    8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码
    IDA使用之旅(一)用IDA查看最简单的sys文件
    IDA使用之旅(三)实践中使用IDA工具
    IDA使用之旅(二)工具及窗口的使用
    正则表达式26英文字母大小写互转
    Ollydbg 中断方法
  • 原文地址:https://www.cnblogs.com/LoveJenny/p/2047116.html
Copyright © 2011-2022 走看看