Работа с сессией из другого потока

rinat.m
Дата: 20.04.2010 12:20:17
есть такой код:
  public partial class WebForm1 : System.Web.UI.Page
    {        
        protected void Page_Load(object sender, EventArgs e)
        {
            Session["test"] = 33;

            Typed.f_ClientID = 55;            

            ThreadStart ts = new ThreadStart(Treat);
            Thread thread = new Thread(ts);
            thread.Start();

            Session["test"] = 88;            
        }

        void Treat()
        {
            try
            {
                int i = (int)Session["test"];
                object obj = Typed.f_ClientID;              
            }
            catch (Exception exc)
            {

            }
        }
    }

   
    public static class Typed
    {   

        public static object f_ClientID
        {
            get { object value; m_SessionGet("ClientID", out value); return value; }
            set { m_SessionSet("ClientID", value); }
        }       
               
        private static void m_SessionGet<T>(String varName, out T value)
        {
            value = (T)HttpContext.Current.Session[varName];
        }       
               
        private static void m_SessionSet<T>(String varName, T value)
        {
            HttpContext.Current.Session[varName] = value;            
        }
    }

вопрос:

почему при работе из другого потока с сессией напрямую всё работает, а при работе через статитеский класс вываливается ошибка?
qu-qu
Дата: 20.04.2010 13:11:20
rinat.m
...
почему при работе из другого потока с сессией напрямую всё работает, а при работе через статитеский класс вываливается ошибка?

Что за ошибка-то?

Судя по этому фрагменту:
...
            catch (Exception exc)
            {

            }
...
- никаких ошибок вообще быть не должно.
rinat.m
Дата: 20.04.2010 13:21:27
qu-qu
rinat.m
...
почему при работе из другого потока с сессией напрямую всё работает, а при работе через статитеский класс вываливается ошибка?

Что за ошибка-то?

Судя по этому фрагменту:
...
            catch (Exception exc)
            {

            }
...
- никаких ошибок вообще быть не должно.


{System.NullReferenceException: Object reference not set to an instance of an object.
bured
Дата: 20.04.2010 13:56:32
Проверяйте на null объект Сессии перед обращением.
qu-qu
Дата: 20.04.2010 13:57:19
rinat.m,

Ну-у-у-у-у, вобщем-то, небольшой поиск по и-нету показал, что HttpContext не "шарится" между потоками, т.е. HttpContext.Current в "чужом" потоке (который не исполняет Page_Load) всегда будет = null...

По здравому размышлению, оно и понятно - у т.н. "конвейера" обработки ASP.NET страницы куча всяких состояний зависит от этого контекста, поэтому ковыряться в нем из постороннего потока - себе дороже...

Для выполнения всяких "долгоиграющих" задач в других потоках рекомендуют использовать Async-модель обработки ASP.NET страницы, там в специальных местах "конвейера" устроены "безопасные разрывы".
qu-qu
Дата: 20.04.2010 14:07:50
bured
Проверяйте на null объект Сессии перед обращением.

Не, Андрюш, это не прокатит: в данном коде Session - это свойство страницы System.Web.UI.Page, оно будет присутствовать в любом потоке, которому доступна сама страница (экземпляр), поэтому оно доступно в экземплярном методе Treat(), хоть они и засунут на выполнение в поток.

А статический метод статического класса Typed ничего не знает об экземпляре страницы, его методах/свойствах и т.д.
Ему надо вытащить ссылку на HttpContext откуда-то извне, а "во вне" у него ничего подобного и нету... (см. пост выше).

З.Ы. единственный выход - цеплять ссылку на текуший HttpContext в сам статический класс прямо перед вызовом его хелперных свойств/методов:
    private static HttpContext _ctx;

    public static void SetContext(HttpContext ctx) { _ctx = ctx; }

    public static string ClientID
    {
        get { string value; GetValue("ClientID", out value); return value; }
        set { SetValue("ClientID", value); }
    }

    private static void SetValue<T>(string key, T value)
    {
        _ctx.Session[key] = value;
    }

    private static void GetValue<T>(string key, out T value)
    {
        value = (T)_ctx.Session[key];
    }
bured
Дата: 20.04.2010 14:34:09
Допустим была бы Сессия out-of-process.
Можно в статике реализовать свой провайдер и передавать в статик session id
SanSYS
Дата: 20.04.2010 21:57:27
qu-qu
bured
Проверяйте на null объект Сессии перед обращением.

Не, Андрюш, это не прокатит: в данном коде Session - это свойство страницы System.Web.UI.Page, оно будет присутствовать в любом потоке, которому доступна сама страница (экземпляр), поэтому оно доступно в экземплярном методе Treat(), хоть они и засунут на выполнение в поток.

А статический метод статического класса Typed ничего не знает об экземпляре страницы, его методах/свойствах и т.д.
Ему надо вытащить ссылку на HttpContext откуда-то извне, а "во вне" у него ничего подобного и нету... (см. пост выше).

З.Ы. единственный выход - цеплять ссылку на текуший HttpContext в сам статический класс прямо перед вызовом его хелперных свойств/методов:
    private static HttpContext _ctx;

    public static void SetContext(HttpContext ctx) { _ctx = ctx; }

    public static string ClientID
    {
        get { string value; GetValue("ClientID", out value); return value; }
        set { SetValue("ClientID", value); }
    }

    private static void SetValue<T>(string key, T value)
    {
        _ctx.Session[key] = value;
    }

    private static void GetValue<T>(string key, out T value)
    {
        value = (T)_ctx.Session[key];
    }


Какого фига такое порно постить??? Вы никогда об асинхронных страницах не слышали?

автору читать:
http://msdn.microsoft.com/en-us/magazine/cc163725.aspx
http://www.gotdotnet.ru/blogs/gaidar/6513/

и если хватит ума, то можно построить целый стек функция, которые должны выполняться и получать доступ к какой-либо странице, и в базовом классы их вызывать, млин RTFM!
ShSerge
Дата: 20.04.2010 22:06:00
Очень сомневаюсь в необходимости (да и вообще в работоспособности) кода с нитками в контексте хттп.
qu-qu
Дата: 21.04.2010 10:06:23
SanSYS
...
Какого фига такое порно постить???
...

Любые вопросы можно решать спокойно, без лишних эмоций...
(человеку захотелось достучаться к HttpContext из статического класса - ему показали как, ничего более).

SanSYS
...
Вы никогда об асинхронных страницах не слышали?
...

Слышал (см. последний абзац текста).