BeginInvoke方法和会话状态

时间:2011-02-23 18:35:42

标签: ajax session asynchronous

我正在调用来自客户端的异步PageMethod调用。后端代码是

[WebMethod(EnableSession = true)]
        public static string BeginMethodCall()
        { //Session Accessible here
            string g = Guid.NewGuid().ToString();                    
            Func<object> f = () => MethodCall();                

            IAsyncResult asyncCall = f.BeginInvoke(null, f);

            lock (AsyncThreadPool)
                AsyncThreadPool[g] = asyncCall;
            return g;
        }            

        [WebMethod(EnableSession=true)]
        public static object EndMethodCall(string guId)
        {
            IAsyncResult callResult;
            lock (AsyncThreadPool)
            {
                callResult = AsyncThreadPool[guId];
                AsyncThreadPool.Remove(guId);
            }

            Func<object> f = (Func<object>)callResult.AsyncState;
            callResult.AsyncWaitHandle.WaitOne();

            return f.EndInvoke(callResult);
        }

        [WebMethod(EnableSession = true)]
        public static object MethodCall()
        {
            //Session not accessible here
        }

会话状态可从BeginMethodCall()EndMethodCall()访问,但不能从MethodCall()访问。

有谁能告诉我为什么我在这里失去会话状态?

  1. 线程是否会丢失Session上下文,因为asyn调用不是线程安全的?
  2. 有没有办法在这里访问会话?

2 个答案:

答案 0 :(得分:0)

如果有人可能会发现这个有用的

由于显而易见的原因,BeginXXX确实创建了一个新的theard并且线程不是会话安全的

答案 1 :(得分:0)

一般来说,

会话+异步=失败

您在回调中以及在分支到异步代码之前是安全的,但是当您并行执行时,您将无法获得完整的会话状态。

但是,有一些解决方法。最简单的是

[SessionState(System.Web.SessionStateBehavior.ReadOnly)]

在控制器级别,显然允许对会话值进行只读访问。只要您不尝试到会话,它就会并行工作。你也可以实现自己的HttpHandler,但那些更难一点。