从另一个线程访问会话数据我有一个问题。在我的网络应用程序中,我有一个页面启动另一个线程,这是一项耗时的任务。在这个新线程中,我调用了我的体系结构的一个方法(在另一个项目-一个体系结构项目中)。问题是:在其中一种方法中,我访问了HttpContext.Current.Session字段。但是当我启动应用程序时,会抛出一个异常,指出对象(HttpContext.Current.Session)有一个空引用。如何将新线程的上下文设置为与HttpApplication上下文相同以便访问HttpContext.Current.Session?这里有很多事情要考虑。如果您的线程的生命周期等于页面的生命周期,并且您需要大量随机访问HttpSessionState,那么您应该从使用静态Current属性创建后台线程的调用中获取SynchronizationContext。一旦你有了它,你就可以将它传递给你的线程,然后当你需要访问与请求相关的HttpContextBase上的任何内容时(这包括会话),你可以调用传递给你的线程的SynchronizationContext上的Post方法获取值(或设置它们)://来自线程服务请求。varsc=同步上下文。当前的;//运行任务Taskt=Task.Run(()=>{//做其他事情。//...//从会话中获取的值。stringsessionValue=null;//需要从会话中获取一些东西吗?sc.Post(()=>{//获取值。sessionValue=HttpContext.Current.Session["sessionValue"];}//做其他事情。//...});这样做很重要,因为可以访问HttpContextBase(和任何东西)与之相关联)不是线程安全的,并且与处理请求的线程(好吧,上下文)无关。请注意,Post方法不会阻塞,因此调用Post后出现的代码(即//Do之后的行其他东西。)应该独立于传递给Post的委托。如果后面的代码是Related,则需要等待调用完成才能继续,然后可以调用Send方法;它具有相同的签名并且会阻塞直到委托中的代码被执行。也就是说,如果你只想对值进行只读访问,最好在调用代码之前获取它们,然后在后台线程中访问它们://在这里获取后台线程中需要的值。varvalues={SessionValue=HttpContext.Current.Session["sessionValue"];};//运行任务Taskt=Task.Run(()=>{//做其他事情。//...//使用会话值。if(values.SessionValue==...)//Do其他的东西。//...});如果您的线程将在为请求提供服务后继续处理,那么您只有只读状态,您必须在启动线程捕获它之前执行此操作。一旦请求被服务,即使会话存在,这是一个逻辑概念;根据会话状态的提供者(会话状态管理器、SQLServer等),每次有新请求进入时,对象都可以被水化。您还必须处理会话超时,您不知道会话是否存在于您要访问它的位置。您不能从线程内访问会话,但可以使用以下方法共享数据:HttpRuntime.Cache但有几点需要牢记:与会话不同,缓存会过期。此外,缓存在所有网络用户之间共享。如果将当前上下文传递给子线程,问题在于它取决于父上下文。如果父上下文终止,那么您的线程将无法再访问上下文并导致问题。一种解决方案是克隆父上下文,然后在线程中使用克隆。这样,如果父线程处置,该线程将继续工作并可以访问所有上下文内容。HttpContextctx=ThreadingFixHttpContext();线程newThread=newSystem.Threading.Thread(newThreadStart(()=>{HttpContext.Current=ctx;Thread.CurrentPrincipal=ctx.User;vartest=HttpContext.Current.Session["testKey"];}));新线程.开始();这也应该与Task.Run()方法一起使用。做这项工作的方法:以上是C#学习教程:从另一个线程访问session数据共享的全部内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注——privatestaticObjectCloneObject(ObjectSource){MemoryStreamStream=newMemoryStream();System.Runtime.Serialization.Formatters.Binary.BinaryFormatterFormatter=newSystem.Runtime.Serialization.Formatters.Binary.BinaryFormatter();Formatter.Serialize(Stream,Source);流.位置=0;对象克隆=(对象)Formatter.Deserialize(Stream);流.关闭();流.处置();返回克隆;}publicstaticSystem.Web.HttpContextThreadingFixHttpContext(){//如果从新线程调用此方法,则存在持有httpContext.current的问题(这是从AniReturnedPaymentsFetch.ascx.cs中的父线程注入的//父httpcurrent将自己死掉(因为它来自不同的线程)//所以我们将它克隆到线程中currentprincipal.System.Security.Principal.WindowsIdentityThreadIdentity=(System.Security.Principal.WindowsIdentity)CloneObject(System.Web.HttpContext.Current.User.Identity);//然后使用parent的request&response创建一个新的httpcontext,所以现在httpcurrent属于这个线程,不会消亡。var请求=System.Web。HttpContext.Current.Request;varresponse=System.Web.HttpContext.Current.Response;varctx=newSystem.Web.HttpContext(请求,响应);ctx.User=newSystem.Security.Principal.WindowsPrincipal(ThreadIdentity);返回ctx;}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处:
