ASP.NET onder de Motorkap: Threading

ASP.NET onder de Motorkap: Threading

ASP.NET is multi-threaded en dat is maar goed ook. De schaalbaarheid van ASP.NET zou om te huilen zijn als dit niet zo was, omdat dan telkens maar één pagina-aanvraag tegelijk afgehandeld zou kunnen worden. Net zoals een grote supermarkt met maar één kassa zou dat tot zeer langzame afhandeling leiden. Door de manier waarop ASP.NET in elkaar zit, biedt multi-threading ons meer dan alleen schaalbaarheid.

Alles draait bij ASP.NET binnen het ASP.NET Worker Process (w3wp.exe of aspnet_wp.exe), waarvan er vanaf IIS 6 meerdere naast elkaar kunnen draaien, elk verantwoordelijk voor één of meer webapplicaties. Daarbij werkt iedere applicatie in een eigen AppDomain binnen het ASP.NET Worker Process. Het ASP.NET Worker Process is in feite een gewoon .NET proces en dat is standaard multi-threaded. Dit betekent dat er een thread pool beschikbaar is met een instelbare hoeveelheid threads. In het geval van ASP.NET bevat de thread pool standaard 25 threads. Wanneer een aanvraag binnenkomt voor een pagina van een bepaalde applicatie (dus AppDomain) kent het ASP.NET Worker Process een thread toe aan dit request om de aanvraag af te handelen. Wanneer de aanvraag afgehandeld is, gaat de thread terug naar de thread pool. De volgende keer dat de thread een aanvraag af moet handelen, kan dit best voor een andere applicatie (dus AppDomain) zijn. Iedere applicatie dient een thread daarom voor iedere aanvraag als nieuw te beschouwen en het is dus bijvoorbeeld niet verstandig om zaken in het geheugen op te slaan dat specifiek is voor de thread (de zogenaamde thread local storage).

Het ASP.NET Worker Process is in feite een gewoon .NET proces en dat is standaard multi-threaded

Doordat threads gedeeld worden door meerdere AppDomains, vraag je je misschien af of dit wel veilig is. Het antwoord is (gelukkig) “ja”. Iedere keer dat een thread uit de thread pool gehaald wordt, krijgt het een context. Deze context bepaalt o.a. de identiteit waaronder de thread werkt en welke Culture en UICulture van toepassing zijn. In het geval van ASP.NET kunnen we daar ook de HttpContext bij tellen, waarmee je toegang hebt tot applicatiegegevens en alle belanghebbende gegevens van de aanvraag, zoals Request, Response, Session en Application. Wanneer de thread klaar is met het afhandelen van de aanvraag, wordt de context van de thread weer in de beginstand teruggebracht. Vanuit het oogpunt van veiligheid betekent dit dat alle aanvraag-, sessie- en applicatiespecifieke gegevens van de vorige aanvraag nooit in de volgende aanvraag beschikbaar zijn. Dit werkt twee kanten op. Het betekent namelijk ook dat we van alles met een thread kunnen doen zonder dat dit invloed heeft op de volgende aanvraag die de thread afhandelt. Zo kunnen we bijvoorbeeld de Culture aanpassen (zie listing 1). In listing 1 zie je de Application_BeginRequest event handler in GLOBAL.ASAX. Deze event handler kijkt naar de waarde van de QueryString parameter ‘lang’ en stelt de Culture van de thread in op de gespecificeerde Culture.

public void Application_BeginRequest(
  object sender, EventArgs e)
{
  string lang = Request.QueryString["lang"];
  if (string.IsNullOrEmpty(lang)) return;
  CultureInfo culture = CultureInfo.GetCultureInfo(lang);
  Thread.CurrentThread.CurrentCulture = culture;
}

Listing 1: De culture van een thread aanpassen



 


   

<%= DateTime.Today.ToLongDateString() %>


 


Listing 2: Testpagina voor Listing 1

Je kunt de code in listing 1 eenvoudig testen door een pagina te maken die de datum toont, zoals in listing 2. Het resultaat van de aanvraag http://localhost/listing2.aspx?lang-=nl-NL is een datum weer in het Nederlands, terwijl http://localhost/listing2.aspx?lang-=fr-FR de datum in het Frans weergeeft. Uiteraard werkt dit ook op basis van andere criteria, zoals een cookie of de URL als de applicatie onder meerdere URL’s bereikbaar is. De code uit listing 1 is dan ook zeker praktisch toepasbaar voor meertalige sites, omdat je daarmee datum- en getalformaten, en het gebruik van resource bestanden kunt sturen.

Het voorgaande voorbeeld is nog betrekkelijk eenvoudig, maar we kunnen nog verder gaan. Als je Forms Authentication gebruikt op basis van Active Directory, log je de gebruikers wel in met username/password uit AD, maar je krijgt niet de rechten van de Windows gebruiker mee zoals met Integrated Security. Je kunt echter de identiteit waaronder de thread draait aanpassen. Hiervoor dien je de WindowsImpersonationContext te gebruiken (die wel FullTrust nodig heeft overigens). Het gebruik daarvan is wat ingewikkeld, maar op m’n blog staat een WrapperImpersonationContext die het allemaal veel eenvoudiger maakt (zie http://www.vanotegem.nl/PermaLink,guid,36633846-2eca-40fe-9957-2859d8a244dc.aspx). Door voor het aanroepen van de pagina in de ASP.NET pipeline de identiteit te veranderen, werkt de hele pagina onder de context van het Windows account van de gebruiker. Zo worden bijvoorbeeld bestanden geopend onder die context en weet je dus zeker dat de gebruiker rechten heeft om dat te doen. In listing 3 zie je de code die hiervoor aan GLOBAL.ASAX toegevoegd moet worden. Denk erom dat er niet altijd een sessiecontext is, vandaar de check op de bestandsextensie. Bij het eerder genoemde blog artikel is de gehele code te downloaden.

WrapperImpersonationContext m_ImpersonationContext;

void Application_EndRequest(object sender, EventArgs e)
{
  if (m_ImpersonationContext != null)
  {
    m_ImpersonationContext.Leave();
  }
}

void Application_PreRequestHandlerExecute(
  object sender, EventArgs e)
{
  if (HttpContext.Current.Request.FilePath.EndsWith(
    ".axd")) return;
  string username = (string)Session["username"];
  string password = (string)Session["password"];
  if (string.IsNullOrEmpty(username) == false)
  {
    m_ImpersonationContext =
      new WrapperImpersonationContext(
        "MyDomain", username, password);
    m_ImpersonationContext.Enter();
  }
}

Listing 3: De identiteit van het Windows account aanpassen

Commentaar van anderen:
ugg boots op 26-7-2010 om 14:02
UGG Upside Boots
ugg boots op 26-7-2010 om 14:04
UGG Boots 5825
ugg boots op 26-7-2010 om 14:05
ghd Iv pink styler
ugg boots op 26-7-2010 om 14:07
Fendi handbags&discount Fendi handbags
ugg boots op 26-7-2010 om 14:08
UGG Classic Boots
ghdivstyler op 7-8-2010 om 9:07
http://www.google.com.hk/search?q=%22Geef+feedback%22+site:www.sdn.nl&hl=zh-CN&newwindow=1&safe=strict&ei=sARdTMy5BYu4uQOQ8pyaDA&start=240&sa=N
uggboots op 9-8-2010 om 11:02
Free Shipping, 100% original quality, authentic ghd hair straighteners on sale! Discount ghd straighteners, up to 50% off retail. Buy your ghd flat iron here. ghd uk ghd ireland ghd newzealand ghd london More and more people like designing their hairstyles by chi flat iron now. Simple but pretty hairstyles made by chi hair straightener become so popular today. Discount chi flat iron can be the best gift for you and your friends
ghd nz op 9-8-2010 om 11:03
Pretty discount louboutin new arrival now!All styles of cheap christian louboutin shoes sale at discount price with 100% highest quality. We guarantee the lowest price online, no sale tex and free shipping. Own your christian louboutin pumps now
Geef feedback:

CAPTCHA image
Vul de bovenstaande code hieronder in
Verzend Commentaar