非同步 HttpContext.Current 為空白null 另一種解決方案

來源:互聯網
上載者:User

標籤:

1、情境

    在匯入通訊錄過程中,把匯入的失敗、成功的號碼數進行統計,然後儲存到session中,用戶端通過輪詢顯示狀態。

    在實現過程中,使用的async調用方法,出現HttpContext.Current為null的情況,如下:

 

2、網路解答

    從百度與Google查詢,分以下兩種情況進行解答:

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,如:

非同步 HttpContext.Current 為空白null 另一種解決方案

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.