c# - 从另一个线程或技巧访问 HttpSessionState (HttpContext.Current.Session)?

标签 c# asp.net multithreading session httpsession

我们有一个网站,它在 App_Code 中实现了中央 HttpSessionState 管理,如下所示:

public static class CurrentSession
{
    public static HttpSessionState Session
    {
        get
        {
            return HttpContext.Current.Session;
        }
    }

    public static bool Exists
    {
        get
        {
            return Session != null ? true : false;
        }
    }
    public static ControlUsu user
    {
        get
        {
            return (ControlUsu)Session["currentuser"];
        }

        set
        {
            Session["currentuser"] = value;
        }
    }
    public static OdbcConnection connection
    {
        get
        {
            return (OdbcConnection)Session["currentconnection"];
        }
        set
        {
            Session["currentconnection"] = value;
        }
    }
    public static OdbcCommand command
    {
        get
        {
            return (OdbcCommand)Session["currentcommand"];
        }
        set
        {
            Session["currentcommand"] = value;
        }
    }
    public static DataTable datatable
    {
        get
        {
            return (DataTable)Session["currentdatatable"];
        }
        set
        {
            Session["currentdatatable"] = value;
        }
    }
    public static OdbcDataAdapter dataadapter
    {
        get
        {
            return (OdbcDataAdapter)Session["currentdataadapter"];
        }
        set
        {
            Session["currentdataadapter"] = value;
        }
    }
    public static Table tablatemp
    {
        get
        {
            return (Table)Session["tablatemp"];
        }
        set
        {
            Session["tablatemp"] = value;
        }
    }

    public static void Init()
    {
        user= new ControlUsu();
        connection= new OdbcConnection();
        command= new OdbcCommand();
        datatable = new DataTable();
        dataadapter = new OdbcDataAdapter();
        tablatemp = new Table();
        //SessionActual.conexion.ConnectionTimeout = 0;
    }
}

使用它的函数类(例如):

public class Funx
{
    public DataTable QuerySQLDT(string SQLx)
    {
        try
        {
            CurrentSession.connection.Open();
        }
        catch (Exception ex)
        {
            ServicioTecnico.EnviarMailError("Error openning connection", ex);
            HttpContext.Current.Response.Redirect("SesionExpirada.aspx", true);
        }
        try
        {
            CurrentSession.command.CommandText = SQLx;
            CurrentSession.dataadapter.SelectCommand = SessionActual.command;

            CurrentSession.datatable.Clear();
            CurrentSession.datatable.Reset();
            CurrentSession.dataadapter.Fill(SessionActual.datatable);

            CurrentSession.connection.Close();
        }
        catch (Exception ex)
        {
            try
            {
                CurrentSession.connection.Close();
            }
            catch { }
            try
            {
                ex.Data.Add("SQLx", SQLx);
                ServicioTecnico.EnviarMailError("Error closing connection", ex);
            }
            catch { }
            throw;
        }

        return CurrentSession.datatable.Copy();
    }
}

所有这一切都很好,直到我们需要在一个新线程中实现一个耗时的过程...... 在第二个线程中,HttpContext.Current.Session 为空(我们知道它是因为线程之间的当前上下文不同)所以一切都失败了:S

经过调查我们发现您可以像这样将 session 从一个线程传递到另一个线程:

 using App_Code;
 public partial class Example: Page
 {
    private void startoperation
    {
        Session["savedsession"] = HttpContext.Current.Session;
        ThreadStart operation = delegate { buscar(); };
        Thread thread = new Thread(operation);
        thread.Start();
    }
    private void longoperation
    {
        HttpSessionState mySession = ((HttpSessionState)Session["savedsession"]);
        //what we would like to do
        //CurrentSession.Session = mySession;

        Funx fun=new Funx();
        DataTable resul=Funx.QuerySQLDT(select * from exampletable");
    }
 }

我们想要做的是将 session 关联到新线程 (CurrentSession.Session = mySession;) 这样每个函数都可以正常工作而无需更改它们(有很多,我们不想更改所有的结构最后添加的应用程序)但是 HttpContext.Current.Session 没有 setter :S(我们知道我们必须将 setter 添加到我们的 CurrentSession.Session 属性)

那么……你会怎么解决呢?有什么大招吗? 我们的一个想法是将 CurrentSession.Session 转换为动态指针或类似的东西,因此当我们要在第二个线程中使用函数时,CurrentSession.Session 的 getter 将从为以下情况传递的临时变量返回 session 线程...但我们不清楚如何实现它...可能的草案是:

public static class CurrentSession
{
    public static HttpSessionState magicpointer;

    public static HttpSessionState Session
    {
        get
        {
            //return HttpContext.Current.Session;
            return magicpointer;
        }
        set
        {
            magicpointer=value;
        }
    }
}

public partial class Example : Page
{
    bool completedtask=false; //we know this would be Session variable or so to work with threads
    private void startoperation
    {
        Session["savedsession"] = HttpContext.Current.Session;
        ThreadStart operation = delegate { buscar(); };
        Thread thread = new Thread(operation);
        thread.Start();
    }
    private void longoperation
    {
        HttpSessionState mySession = ((HttpSessionState)Session["savedsession"]);

        CurrentSession.Session = mySession;
        //or set the magicpointer...whatever works...
        CurrentSession.magicpointer= mySession;

        Funx fun=new Funx();
        DataTable resul=Funx.QuerySQLDT(select * from exampletable");

        //time consuming work...

        completedtask=true; //change the flag so the page load checker knows it...
    }
    private void page_load_checker()
    { //this combined with javascript that makes the page postback every 5 seconds or so...
       if(completedtask)
       {
           //show results or something like that
           //set the CurrentSession.magicpointer or CurrentSession.Session 
           //to point the HttpContext.Current.Session again...
           CurrentSession.magicpointer=HttpContext.Current.Session;
       }
    }
}

这就是历史……很抱歉让这篇文章写得太久,但我们想弄清楚情况,以防止混淆和出现偏差的答案……谢谢!

最佳答案

重构您的代码可能会更好地为您服务。让您的函数实际采用它们操作的参数,而不是依赖于环境(在 session 中)存在的数据。如果您有一个函数需要知道当前用户是谁,请告诉它当前用户是谁。

关于c# - 从另一个线程或技巧访问 HttpSessionState (HttpContext.Current.Session)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4275642/

相关文章:

java - 为什么Thread.isInterrupted()总是返回false?

c# - 如何检查程序集的类型是否为 ComVisible

c# - 是否可以通过一个连接在 .Net 中实现异步 Web 服务调用?

c# - 匹配 href 的正则表达式,但没有媒体文件

c++ - sleep_until 过去的某个时间点

java - 测试 SimpleDateFormat 的多线程调用

c# - 在 WPF 中渲染清晰的线条

c# - 将嵌套 ListView 的数据源绑定(bind)到父级 ListView 的数据源

javascript - 发布到相对 url

c# - 替换动态字符串中的部分文本