Jak přistupovat na HttpContext.Current v novém threadu

Když si v ASP.NET spustíme nový thread (vlákno), tak tento sice získá některé vlastnosti z původního threadu (např. culture), ale nemá přístup k HttpContext.Current, resp. je v něm null.

V každém případě musíme vědět, co děláme, protože druhé vlákno například nemůže moc manipulovat s Response, neboť není vůbec jisté, do jakého stavu Response uvedl thread první, např. už totiž mohl Response odeslat na klienta.

Společné uložiště threadů – statická property

První možností je připravit hodnoty, které bude nový thread potřebovat, do uložiště, které je přístupné oboum threadům, klasicky třeba statické property nějaké třídy.

public static string RootUrl
{
   get
   {
      if (rootUrl == null)
      {
         if (HttpContext.Current != null)
         {
            rootUrl = "http://" + HttpContext.Current.Request.Url.Host + HttpContext.Current.Request.ApplicationPath;
         }
         else
         {
            rootUrl = "http://nejaky/default/url";
         }
      }
      return rootUrl;
   }
}
private static string rootUrl;

Výše uvedený příklad statické property zahrnuje i určitou logiku. Rozhodující je však uložení výsledku prvního volání do statické privátní proměnné rootUrl. Pokud si tedy před spuštěním nového threadu zaručíme alespoň jedno čtení dané property, ta si inicializuje svojí hodnotu v prvním threadu a v druhém threadu už dá rovnou výsledek připravený v rootUrl (nebude HttpContext.Current potřebovat).

Teoreticky lze do statické property typu HttpContext cachovat celý HttpContext.Current, nepovažuji to však za příliš vhodné.

Předání contextu v instanci třídy zapouzdřující thread

Druhou možností, která je vhodnější, pokud už potřebujeme předat do druhého threadu opravdu celý context, je zapouzdření druhého threadu do samostatné třídy:

public class MyClass 
{ 
   private HttpContext _context; 
   public MyClass(HttpContext context)
   {
      _context = context;
   } 
   public void Start() 
   { 
      ThreadStart start = new ThreadStart(DoWork); 
      Thread.Start(start); 
   } 
   private void DoWork() 
   { 
      // tady můžem něco dělat z contextem,
      // ale pozor, že request už může být odeslán na klienta
   } 
} 

private void Page_Load(object sender, EventArgs e) 
{ 
   MyClass myClass = new MyClass(HttpContext.Current); 
   myClass.Start(); 
}
HttpContext.Current.Cache

Pokud potřebujeme jen HttpContext.Current.Cache, tak je vše výše uvedené nesmysl, protože na cache máme přístupovat přes HttpRuntime.Cache, a to funguje i v novým threadu…

Napsat komentář

Vyplňte detaily níže nebo klikněte na ikonu pro přihlášení:

WordPress.com Logo

Komentujete pomocí vašeho WordPress.com účtu. Log Out / Změnit )

Twitter picture

Komentujete pomocí vašeho Twitter účtu. Log Out / Změnit )

Facebook photo

Komentujete pomocí vašeho Facebook účtu. Log Out / Změnit )

Google+ photo

Komentujete pomocí vašeho Google+ účtu. Log Out / Změnit )

Připojování k %s