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
/// </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 };
}
/// 获取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);
}
/// 调用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);
}
}
}
/// 同步处理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);
}
}
}
作者:LoveJenny
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。