none
多线程下如何共享主线程的session? RRS feed

  • 问题

  • 在web下面,我要用n个线程来下载同一个文件,每个进程负责下载文件的一个片段,这个下载文件片段的函数里面包含用户登陆的认证,如果没有登陆,不给下载,可是我发现,用了多线程以后,每个线程共享不到主线程的session,也就是之前登陆创建的session在每个进程下访问不到
    http://www.mapgou.cn
    2009年9月8日 9:07

答案

  • 这是可行的如下代码
    ----------------------------------------------
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Threading;
    
    public partial class Default8 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // 设置 Session
            Session["IsLogin"] = true;
    
            List<Thread> lst = new List<Thread>();
            
            for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(new ThreadStart(DoWork));
                t.Name = string.Format("Thread-{0}", i);
                lst.Add(t);
            }
    
            foreach (Thread t in lst)
            {
                t.Start();
            }
        }
    
        private void DoWork()
        {
            while (true)
            {
                if (Session["IsLogin"] != null)
                {
                    Boolean IsLogin = (Boolean)Session["IsLogin"];
                }
    
                String CurrentThreadName = Thread.CurrentThread.Name;
    
                Thread.Sleep(1000);
            }
        }
    }
    


    知识改变命运,奋斗成就人生!
    2009年9月9日 3:06
    版主
  • 放到别的类文件里面?
    这个没试过。一个做法是你可以在类的实例化的时候将 HttpContext.Current 作为参数传递过去啊

    【孟子E章】
    2009年9月10日 1:08
    版主
  • 放到别的类文件里面?
    这个没试过。一个做法是你可以在类的实例化的时候将 HttpContext.Current 作为参数传递过去啊

    【孟子E章】

    正解

    平时的 session 是从httpcontext.current  从当前线程取出的     取出了以后就不会变了
    恭喜自己5星用户达成
    2009年9月10日 3:12

全部回复

  • 既然要在多个帐号间共享可以考虑 Cache 或 Application 
    知识改变命运,奋斗成就人生!
    2009年9月8日 9:36
    版主
  • 既然要在多个帐号间共享可以考虑 Cache 或 Application 
    知识改变命运,奋斗成就人生!

    Application 是全局的,我意思一个用户,登陆后,信息保存session里面,当他多线程下载文件时,如何让每个线程都可以共享他登陆的session信息

    http://www.mapgou.cn
    2009年9月8日 9:38
  • 好复杂啊
    聚信与共 ,创赢未来 如果问题没有解决,请继续跟帖讨论;如果问题得到解决,请标记为答复。有帮助请投票
    2009年9月8日 9:42
  • 按你的描述是是可以的呀,你看看是不是其它地方出了问题。
    知识改变命运,奋斗成就人生!
    2009年9月8日 9:53
    版主
  • 您好,在web下如何开启多线程?
    通过打开多个网页?
    如果是,则在登入的那个网页上点击来打开下载其它部分的网页。
    2009年9月8日 12:26
    版主
  • 难道客户端没有保存session cookie?

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
    2009年9月8日 15:53
    版主
  • 先成功登录后再开启多个线程
    【孟子E章】
    2009年9月9日 1:20
    版主
  • 先成功登录后再开启多个线程
    【孟子E章】

    我再把我的问题简化下,简化代码如下:

    if(Session["_xx_xxx_xx"] != null)//主线程的if语句,在登陆成功后,这个if会返回true
    {
    //开启10个线程(每个线程调用函数Run);
    ......
    }

    //每个线程调用的方法
    void Run()
    {
    if(Session["_xx_xxx_xx"] != null)//线程的回话,即使登陆后,这个if语句也总是返回false,所以里面的代码不能执行
    {
    //开始下载文件(登陆用户才能下载,所以我做了限制);
    ......
    }
    }

    我个人的理解,主线程创建的线程已经是另外的回话了,所以不能共用,不知道有啥办法可以共享主线程的session

    http://www.mapgou.cn
    2009年9月9日 2:54
  • 这是可行的如下代码
    ----------------------------------------------
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Threading;
    
    public partial class Default8 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // 设置 Session
            Session["IsLogin"] = true;
    
            List<Thread> lst = new List<Thread>();
            
            for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(new ThreadStart(DoWork));
                t.Name = string.Format("Thread-{0}", i);
                lst.Add(t);
            }
    
            foreach (Thread t in lst)
            {
                t.Start();
            }
        }
    
        private void DoWork()
        {
            while (true)
            {
                if (Session["IsLogin"] != null)
                {
                    Boolean IsLogin = (Boolean)Session["IsLogin"];
                }
    
                String CurrentThreadName = Thread.CurrentThread.Name;
    
                Thread.Sleep(1000);
            }
        }
    }
    


    知识改变命运,奋斗成就人生!
    2009年9月9日 3:06
    版主
  • 你使用的是iis6或者之后的iis吧,看看应用程序池-性能-Web园数目是不是设置大于1了
    【孟子E章】
    2009年9月9日 3:12
    版主
  • 我想请教各位,即使Session问题解决了,那么这段代码是在服务器端运行的,客户端如何享受到多线程?
    还是说服务器上下载别的服务器的文件?然后汇总再传给客户端?
    2009年9月9日 3:26
    版主
  • 我想请教各位,即使Session问题解决了,那么这段代码是在服务器端运行的,客户端如何享受到多线程?
    还是说服务器上下载别的服务器的文件?然后汇总再传给客户端?
    是啊,这个代码怪怪的,你的一个程序里,Session是不会丢失的,提问的人没有搞清楚怎么问
    【孟子E章】
    2009年9月9日 4:09
    版主
  • 这是可行的如下代码
    ----------------------------------------------
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Threading;
    
    public partial class Default8 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // 设置 Session
            Session["IsLogin"] = true;
    
            List<Thread> lst = new List<Thread>();
            
            for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(new ThreadStart(DoWork));
                t.Name = string.Format("Thread-{0}", i);
                lst.Add(t);
            }
    
            foreach (Thread t in lst)
            {
                t.Start();
            }
        }
    
        private void DoWork()
        {
            while (true)
            {
                if (Session["IsLogin"] != null)
                {
                    Boolean IsLogin = (Boolean)Session["IsLogin"];
                }
    
                String CurrentThreadName = Thread.CurrentThread.Name;
    
                Thread.Sleep(1000);
            }
        }
    }
    
    


    知识改变命运,奋斗成就人生!



    你的代码,很接近我的代码,测试是成功的。
    但是,你试试再将你的DoWork方法放到别的类文件里面,就不能运行啦。

    我发现通过web启动多线程,多线执行的代码就想控制台代码一样,HttpContext.Current始终为null,所以session对象也是没有实例化的,我看我的想法是行不通了,用session保存回话状态不行


    http://www.mapgou.cn
    2009年9月10日 0:47
  • 放到别的类文件里面?
    这个没试过。一个做法是你可以在类的实例化的时候将 HttpContext.Current 作为参数传递过去啊

    【孟子E章】
    2009年9月10日 1:08
    版主
  • 放到别的类文件里面?
    这个没试过。一个做法是你可以在类的实例化的时候将 HttpContext.Current 作为参数传递过去啊

    【孟子E章】

    正解

    平时的 session 是从httpcontext.current  从当前线程取出的     取出了以后就不会变了
    恭喜自己5星用户达成
    2009年9月10日 3:12
  • 放到别的类文件里面?
    这个没试过。一个做法是你可以在类的实例化的时候将 HttpContext.Current 作为参数传递过去啊

    【孟子E章】

    这也是唯一的办法了,刚刚把代码改了,传参数进去可以解决问题,谢了,也谢谢大家~~~~~~~~~

    http://www.mapgou.cn
    2009年9月10日 3:51
  • .Net 提供了一个 ASP.NET State Service 的系统服务,就是解决WEB服务器运行在多线程时的session共享问题。

    与此同时,还需要简单的更改一下站点webconfig的session配置部分。

    然后,session的访问和原来没有任何区别,源代码不需要任何变动。
    2009年9月12日 8:49
  • while (true) 在有Session的页面, 只能有一条线程... 其他的好像会被卡住,等前一条走完,才能下一个才运行....
    2011年4月7日 8:13