4

我有一个场景,我有一个页面,在单击按钮时打开一个对话框,在按钮单击打开的对话框表单中,我可以从选定的 .txt 文件中读取数据列表并构建查询并将数据添加到一些数据库表。由于可能存在大量数据,因此此过程可能需要很长时间,因此用户在上传完成之前将无法在应用程序上工作。因此,为了使上传过程异步,我正在使用 PageAsyncTask。下面是代码示例,但在 PageAsyncTask 中调用的方法中,HttpContext.Current 为空,因此我无法使用会话处理。请对此提供任何指导,为什么这是空的,在这种情况下我如何使用会话

   protected void BtnUpload_click(object sender, EventArgs e)
    {
        PageAsyncTask asyncTask1 = new PageAsyncTask(OnBegin, OnEnd, OnTimeout, SessionManager.UserData, true);

        Page.RegisterAsyncTask(asyncTask1);
        Page.ExecuteRegisteredAsyncTasks();
    }

public IAsyncResult OnBegin(object sender, EventArgs e,
            AsyncCallback cb, object extraData)
    {
        _taskprogress = "AsyncTask started at: " + DateTime.Now + ". ";
        uData = extraData as UserData;

        _dlgt = new AsyncTaskDelegate(BeginInvokeUpload);
        IAsyncResult result = _dlgt.BeginInvoke(cb, extraData);

        return result;
    }

private void BeginInvokeUpload()
    {
        string selectedFileName = string.Empty;
        string returnValuePage = string.Empty;
        User teller = new User();
        SessionManager.UserData = uData;
    }



  private void BeginInvokeUpload()
    {
        string selectedFileName = string.Empty;
        string returnValuePage = string.Empty;
        User teller = new User();
        SessionManager.UserData = uData;
    }

public class SessionManager
    {
public static UserData UserData
        {
            get 
            {
                UserData userData = null;
                if (HttpContext.Current.Session["UserData"] != null)
                {
                    userData = HttpContext.Current.Session["UserData"] as UserData;                    
                }
                return userData;
            }
            set 
            {
                 HttpContext.Current.Session["UserData"]=value;                  
            }
        }
}
4

1 回答 1

4

答案很简单:如果HttpContext.Current is null

因此,如果您需要修改会话,您不能简单地修改,唯一的选择是制作您完全自定义的会话模块/解决方案。

如果您只需要读取一些值,那么您可以在创建线程时传递它们。

最后,唯一的解决方案是如果您成功操纵会话变量,则不要使用线程。

为什么这个设计?

为什么 MS 会话不允许您在页面外和线程内处理它?答案是因为需要在页面处理时锁定会话数据——有了这个锁,即使你启动一个线程并且能够获取会话数据,也无法并行使用它。

另外如果你能够在一个线程中使用自己的会话,那么这个线程可能会锁定整个页面查看过程,因为我再说一遍,会话是锁定整个页面查看,并且使用相同会话的每个页面都不会并行工作

整个页面上的会话锁定是 MS 会话工作方式所必需的,避免这种情况的唯一方法是制作完全自定义的会话解决方案,并使用不同的代码处理特殊情况。

该设计的好处是您避免在每次页面调用时自行进行大量锁定和同步 - 例如,如果您禁用页面上的会话,并使用该页面插入数据,如果使用 make multiple double单击插入,并且您没有在插入上同步处理它,您最终会得到多个相同的插入。

有关会话锁定的更多信息:
完全替换 ASP.Net 的会话
Web 应用程序在共享同一会话时处理另一个 Web 应用程序时被阻止
jQuery Ajax 对 Web 服务的调用似乎是同步的
ASP.NET 服务器不会异步处理页面

类似的问题:
How to get Session Data without having HttpContext.Current, by SessionID

于 2012-12-12T16:08:29.367 回答