文章出處
文章列表
1、場景
在導入通訊錄過程中,把導入的失敗、成功的號碼數進行統計,然后保存到session中,客戶端通過輪詢顯示狀態。
在實現過程中,使用的async調用方法,出現HttpContext.Current為null的情況,如下:
2、網絡解答
從百度與谷歌查詢,分以下兩種情況進行解答:
1、更改web.config配置文件
Stackoverflow給出如下解決方案:http://stackoverflow.com/questions/18383923/why-is-httpcontext-current-null-after-await
2、緩存HttpContext
博客地址:http://www.cnblogs.com/pokemon/p/5116446.html
本博客,給出了異步下HttpContext.Current為空的原因分析。本文中的最后提取出如下方法:
using System; using System.Linq.Expressions; using System.Reflection; using System.Threading; using System.Web; namespace TxSms { /// <summary> /// 解決Asp.net Mvc中使用異步的時候HttpContext.Current為null的方法 /// <remarks> /// http://www.cnblogs.com/pokemon/p/5116446.html /// </remarks> /// </summary> public static class HttpContextHelper { /// <summary> /// 在同步上下文中查找當前會話<see cref="System.Web.HttpContext" />對象 /// </summary> /// <param name="context"></param> /// <returns></returns> public static HttpContext FindHttpContext(this SynchronizationContext context) { if (context == null) { return null; } var factory = GetFindApplicationDelegate(context); return factory?.Invoke(context).Context; } private static Func<SynchronizationContext, HttpApplication> GetFindApplicationDelegate(SynchronizationContext context) { Delegate factory = null; Type type = context.GetType(); if (!type.FullName.Equals("System.Web.LegacyAspNetSynchronizationContext")) { return null; } //找到字段 ParameterExpression sourceExpression = Expression.Parameter(typeof(SynchronizationContext), "context"); //目前支持 System.Web.LegacyAspNetSynchronizationContext 內部類 //查找 private HttpApplication _application 字段 Expression sourceInstance = Expression.Convert(sourceExpression, type); FieldInfo applicationFieldInfo = type.GetField("_application", BindingFlags.NonPublic | BindingFlags.Instance); Expression fieldExpression = Expression.Field(sourceInstance, applicationFieldInfo); factory = Expression.Lambda<Func<SynchronizationContext, HttpApplication>>(fieldExpression, sourceExpression).Compile(); //返回委托 return ((Func<SynchronizationContext, HttpApplication>)factory); } /// <summary> /// 確定異步狀態的上下文可用 /// </summary> /// <param name="context"></param> /// <returns></returns> public static HttpContext Check(this HttpContext context) { return context ?? (context = SynchronizationContext.Current.FindHttpContext()); } } }
3、實現
通過2對兩種方法都進行嘗試,發現還是不可用的。使用session共享數據行不通,換另外一種思路,使用cache,封裝類庫如下:
using System; using System.Collections; using System.Web; using System.Web.Caching; namespace TxSms { /// <summary> /// HttpRuntime Cache讀取設置緩存信息封裝 /// <auther> /// <name>Kencery</name> /// <date>2015-8-11</date> /// </auther> /// 使用描述:給緩存賦值使用HttpRuntimeCache.Set(key,value....)等參數(第三個參數可以傳遞文件的路徑(HttpContext.Current.Server.MapPath())) /// 讀取緩存中的值使用JObject jObject=HttpRuntimeCache.Get(key) as JObject,讀取到值之后就可以進行一系列判斷 /// </summary> public static class HttpRuntimeCache { /// <summary> /// 設置緩存時間,配置(從配置文件中讀取) /// </summary> private const double Seconds = 30 * 24 * 60 * 60; /// <summary> /// 緩存指定對象,設置緩存 /// </summary> public static bool Set(string key, object value) { return Set(key, value, null, DateTime.Now.AddSeconds(Seconds), Cache.NoSlidingExpiration, CacheItemPriority.Default, null); } /// <summary> /// 緩存指定對象,設置緩存 /// </summary> public static bool Set(string key, object value, string path) { try { var cacheDependency = new CacheDependency(path); return Set(key, value, cacheDependency); } catch { return false; } } /// <summary> /// 緩存指定對象,設置緩存 /// </summary> public static bool Set(string key, object value, CacheDependency cacheDependency) { return Set(key, value, cacheDependency, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null); } /// <summary> /// 緩存指定對象,設置緩存 /// </summary> public static bool Set(string key, object value, double seconds, bool isAbsulute) { return Set(key, value, null, (isAbsulute ? DateTime.Now.AddSeconds(seconds) : Cache.NoAbsoluteExpiration), (isAbsulute ? Cache.NoSlidingExpiration : TimeSpan.FromSeconds(seconds)), CacheItemPriority.Default, null); } /// <summary> /// 獲取緩存對象 /// </summary> public static object Get(string key) { return GetPrivate(key); } /// <summary> /// 判斷緩存中是否含有緩存該鍵 /// </summary> public static bool Exists(string key) { return (GetPrivate(key) != null); } /// <summary> /// 移除緩存對象 /// </summary> /// <param name="key"></param> /// <returns></returns> public static bool Remove(string key) { if (string.IsNullOrEmpty(key)) { return false; } HttpRuntime.Cache.Remove(key); return true; } /// <summary> /// 移除所有緩存 /// </summary> /// <returns></returns> public static bool RemoveAll() { IDictionaryEnumerator iDictionaryEnumerator = HttpRuntime.Cache.GetEnumerator(); while (iDictionaryEnumerator.MoveNext()) { HttpRuntime.Cache.Remove(Convert.ToString(iDictionaryEnumerator.Key)); } return true; } /// <summary> /// 設置緩存 /// </summary> public static bool Set(string key, object value, CacheDependency cacheDependency, DateTime dateTime, TimeSpan timeSpan, CacheItemPriority cacheItemPriority, CacheItemRemovedCallback cacheItemRemovedCallback) { if (string.IsNullOrEmpty(key) || value == null) { return false; } HttpRuntime.Cache.Insert(key, value, cacheDependency, dateTime, timeSpan, cacheItemPriority, cacheItemRemovedCallback); return true; } /// <summary> /// 獲取緩存 /// </summary> private static object GetPrivate(string key) { return string.IsNullOrEmpty(key) ? null : HttpRuntime.Cache.Get(key); } } }
在此調試,完全可以找到((ImportContactStateModel)model).SuccessNum,如下圖:
文章列表
全站熱搜