Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET HttpContext缓存在插入后立即删除_C#_Asp.net_Asp.net Mvc_Csv_Caching - Fatal编程技术网

C# ASP.NET HttpContext缓存在插入后立即删除

C# ASP.NET HttpContext缓存在插入后立即删除,c#,asp.net,asp.net-mvc,csv,caching,C#,Asp.net,Asp.net Mvc,Csv,Caching,我有一个ASP.NET 4 web服务。 它在模块控制器控制器中有一个导入模块操作 这就是它的工作原理: 用户将模块上载为CSV文件 正在使用HttpPostedFileBase.InputStream和自定义CSV读取类读取此文件 根据一些规则和验证,此文件正在转换为C#对象。如果文件有效,则它将转换为C#对象,以唯一的GUID名称存储在缓存中,并将用户重定向到CompleteImportModule操作 用户检查数据是否正确,并确认上传 长话短说,这里有一个代码告诉您更多信息: Import

我有一个ASP.NET 4 web服务。
它在
模块控制器
控制器中有一个
导入模块
操作

这就是它的工作原理:

  • 用户将模块上载为CSV文件
  • 正在使用
    HttpPostedFileBase.InputStream
    和自定义CSV读取类读取此文件
  • 根据一些规则和验证,此文件正在转换为C#对象。如果文件有效,则它将转换为C#对象,以唯一的GUID名称存储在缓存中,并将用户重定向到
    CompleteImportModule
    操作
  • 用户检查数据是否正确,并确认上传
  • 长话短说,这里有一个代码告诉您更多信息:
    ImportModule
    操作

    public ActionResult ImportModule(HttpPostedFileBase file)
    {
        if (!ModelState.IsValid) 
        {
            return RedirectToAction("Index");
        }
    
        ModuleQuestion[] questions;
        ModuleInfo moduleInfo;
        string uploadId = Guid.NewGuid().ToString();
    
        // It is my custom CSV-reader and it works. Values are assigned
        FormDataCsvReader csvReader = new FormDataCsvReader(file.InputStream);
        if (!csvReader.Process(out questions, out moduleInfo))
        {
            // File is invalid
            return RedirectToAction("Index");
        }
    
        ViewBag.UploadId = uploadId;
        ViewBag.ModuleInfo = moduleInfo;
        ViewBag.Questions = questions;
    
        HttpContext.Cache.Add("UploadModule_" + uploadId,
            new Tuple<ModuleInfo, ModuleQuestion[]>(moduleInfo, questions),
            null,
            Cache.NoAbsoluteExpiration,
            TimeSpan.FromMinutes(30),
            CacheItemPriority.NotRemovable,
            (k, v, r) => 
            {
                LoggingFactory.GetLogger().Debug("Removed from cache: {0}. Reason: {1}", k, r);
            });     
    
        return View();   
    }
    
    CompleteImportModule
    操作:

    [HttpPost]
    public ActionResult CompleteImportModule(string uploadId)
    {
        var item = HttpContext.Cache["UploadModule_" + uploadId];
        if (item == null) RedirectToAction("Index");
        // upload module 
        HttpContext.Cache.Remove("UploadModule_" + uploadId);
        return RedirectToAction("Index");
    }
    
    然而,我遇到了一些问题。我无法上载模块,因为该值在插入后立即从缓存中删除。它仅存储一秒钟:

    DEBUG 2015-06-22 15:00:18,696 thread 85: Added to cache:
    UploadModule_c843077d-21d0-4e9f-9e5e-3df82da4bac8
    
    DEBUG 2015-06-22 15:00:19,935 thread 48: Removed from cache:
    UploadModule_c843077d-21d0-4e9f-9e5e-3df82da4bac8. Reason: Removed
    
    原因
    是“删除”的,这意味着它没有过期,并且由于优化,IIS没有删除它,但看起来我删除的是我自己。 我非常确定在
    CompleteImportModule
    之前我甚至没有访问这个缓存记录

    我已尝试将
    new StackTrace().ToString()
    放入
    CacheItemRemovedCallback
    中。就这样,如果它能有所帮助的话:

    at CPMAdministrator.Controllers.ModulesReferenceController.<ImportModule>b__9(String key, Object value, CacheItemRemovedReason reason)
       at System.Web.Caching.CacheEntry.CallCacheItemRemovedCallback(CacheItemRemovedCallback callback, CacheItemRemovedReason reason)
       at System.Web.Caching.CacheEntry.Close(CacheItemRemovedReason reason)
       at System.Web.Caching.CacheSingle.UpdateCache(CacheKey cacheKey, CacheEntry newEntry, Boolean replace, CacheItemRemovedReason removedReason, Object& valueOld)
       at System.Web.Caching.CacheSingle.Dispose(Boolean disposing)
       at System.Web.Caching.CacheMultiple.Dispose(Boolean disposing)
       at System.Web.HttpRuntime.Dispose()
       at System.Web.HttpRuntime.ReleaseResourcesAndUnloadAppDomain(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
       at System.Threading.ThreadPoolWorkQueue.Dispatch()
    
    位于cpmdinistrator.Controllers.ModulesReferenceController.b__9(字符串键、对象值、CacheItemRemovedReason)
    位于System.Web.Caching.CacheEntry.CallCacheItemRemovedCallback(CacheItemRemovedCallback回调,CacheItemRemovedReason)
    位于System.Web.Caching.CacheEntry.Close(CacheItemRemovedReason)
    位于System.Web.Caching.CacheSingle.UpdateCache(CacheKey CacheKey、CacheEntry newEntry、Boolean replace、CacheItemRemovedReason removedReason、Object&valueOld)
    位于System.Web.Caching.CacheSingle.Dispose(布尔值disposing)
    位于System.Web.Caching.CacheMultiple.Dispose(布尔disposing)
    在System.Web.HttpRuntime.Dispose()上
    位于System.Web.HttpRuntime.ReleaseResources和UnloadappDomain(对象状态)
    位于System.Threading.ExecutionContext.RunInternal(ExecutionContext ExecutionContext、ContextCallback回调、对象状态、布尔值preserveSyncCtx)
    在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态,布尔保存SyncCTX)
    位于System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()处
    在System.Threading.ThreadPoolWorkQueue.Dispatch()中
    

    为什么会这样?这是一种IIS池回收吗?如何确保文件未被删除?或者如何以另一种方式有效地存储此数据?

    给出的删除原因是
    已删除
    ,这意味着:

    通过Remove方法调用或指定相同键的Insert方法调用从缓存中删除该项


    因此,您要么在其他地方显式调用了
    Remove
    ,要么用
    Insert

    覆盖它。我花了几个小时寻找答案,并在发布问题后立即找到了答案!让我和你分享我的经验

    根据我的StackTrace,我知道缓存已被清除,因为应用程序已结束并被释放:

    at System.Web.HttpRuntime.Dispose()
    at System.Web.HttpRuntime.ReleaseResourcesAndUnloadAppDomain(Object state)
    
    我所需要的就是找到原因

    我已经打开了我的
    Global.asax
    文件,并添加了一个
    Application\u End
    方法

    public class MvcApplication : HttpApplication
    {
        protected void Application_End()
        {
        }
    }
    
    它在视图渲染成功之后和缓存清除之前立即触发。成功!现在我需要知道申请结束的原因

    帮助我:

    System.Web.Hosting.HostingEnvironment.ShutdownReason
    属性,该属性指示终止应用程序的原因。它的 可以从
    应用程序\u End()
    内部检索值

    我在
    Application\u End
    的开头添加了一个断点,并添加了
    System.Web.Hosting.HostingEnvironment.ShutdownReason
    来观看

    这就是它存储的内容:
    bindirchangerdirectoryrename

    之后,我明白了原因是我的
    log4net
    正在
    BinDirectory
    中编写日志。如果
    bin
    目录被更改,我就不知道IIS正在完成web应用程序

    我已将日志移到父文件夹(应用程序本身)中,现在它可以工作了。
    看来我需要更多地了解ASP.NET。

    我希望它能帮助别人。感谢所有试图提供帮助的人。

    这是在生产环境中还是通过VS进行调试?@heymega这是VS在开发人员的机器上进行调试。谢谢。我找到了解决办法!阅读我自己的答案。是的,确实,远离你的bin目录!:)
    public class MvcApplication : HttpApplication
    {
        protected void Application_End()
        {
        }
    }