[ASP.Net] asp.net threadsafe maken Overzicht Laatste deel

Dit topic is onderdeel van een reeks. Ga naar het meest recente topic in deze reeks.

Pagina: 1
Acties:
  • 1.969 views

Onderwerpen


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Beste mensen,

Ik heb hier in mijn applicatie geconcludeerd dat een bepaalde functie van mij niet threadsafe is, maar kan het niet verklaren.
Kan iemand mij helpen?

korte situatieschets:

ik heb een asp.net app, met daarin een aantal pagina's. Op verschillende plekken in de applicatie doe ik iets met de username van de ingelogde gebruiker.

De gebruiker logt in in IIS (windows auth, gebeurd automagisch) en ik wil de gebruikersnaam van de in IIS al geauthenticeerde gebruiker laten zien of gebruiken.

Ik heb daarvoor een volgende constructie:

C#:
1
2
3
4
5
6
7
8
9
10
11
public static class Helper 
{
    public static GetUserName()
    {
        if (HttpContext.Current.User != null)
        {
            return Regex.Replace(HttpContext.Current.User.Identity.Name, @"(.*?\\)?(.*?)", "$2");
        }
        return "";  //hier is IIS neit goed geconfigt
    }
}


en een aantal pagina's gebruiken die functie dus dmv:

C#:
1
string s = Helper.GetUserName();


Nu heb ik de methode omgebouwd zodat het een instance method is geworden en dan zie ik dat het goed gaat.
Echter kan ik niet beredeneren waarom het fout zou moeten gaan.

De Regex.Replace had ik al opgezocht is immutable (dus threadsafe)

Verder zou het natuurlijk best kunnen dat er een contextswitch is ergens in die code, maar ik bevraag telkens de HttpContext.Current en die zou (zoals ze dat leuk zeggen) effectively threadsafe moeten zijn.

Ik sla bij mijn weten de inhoud van die httpcontext.current niet op, zodat een andere thread ermee vandoor kan gaan.


Wat doe ik fout?

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Sowieso kan tussen de HttpContext.Current.User != null check en de regex een context-switch optreden.

https://niels.nu


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 23:11

Haan

dotnetter

Gebruik maken van static variabelen of methods in een web applicatie is vaak vragen om problemen.
Zo heb ik ook een keer meegemaakt dat iemand een static List bijhield in een webpagina, en het vervolgens vreemd vond dat gebruikers elkaars data aan het overschrijven waren :X

Wat dat betreft is de VB.NET benaming 'Shared' wat duidelijker dan C#.

[ Voor 11% gewijzigd door Haan op 03-10-2012 14:02 ]

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • boe2
  • Registratie: November 2002
  • Niet online

boe2

'-')/

Een static class in asp.net gaat over heel je server, niet over 1 gebruikersessie. Wat Haan zegt dus :)

[ Voor 16% gewijzigd door boe2 op 03-10-2012 14:15 ]

'Multiple exclamation marks,' he went on, shaking his head, 'are a sure sign of a diseased mind.' - Pratchett.


Acties:
  • 0 Henk 'm!

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Echter kan ik niet beredeneren waarom het fout zou moeten gaan.
Hoe gaat het fout dan? Je zegt dat je code niet thread-safe is, maar waaraan merk je dat?

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Mensen mensen, ik weet hoe static werkt, ik weet dat dit over alle requests/users heen gaat, en dat ze dus dezelfde waarde gebruiken.

Echter wat ik niet snap is waarom hier (zelfs met context switches) iets fout zou kunnen gaan.

@MrBucket:
Ik laat op een bepaalde pagina direct die username zien (als soort van debug).
Hier zien gebruikers soms namen van andere gebruikers staan.

@Hydra:
Ja dat klopt. Maar waarom zou het dan fout gaan?

In de regel er onder maak ik gebruik van 'HttpContext.Current.User.Identity.Name'
Die is dus weer van de gebruiker (thread) die op dat moment aan't bevragen is.

Ik return hem ook direct, en sla hem dus niet eerst op (waar een contextswitch tussen kan optreden)

Als hij een contextswitch geeft tussen de nullcheck en de regex dan zou in het ergste geval hij voor de check niet null zijn, en daarna wel en dus een nullrefException gooien. Echter heb ik die nog nooit gehad. (omdat anonymous access uit staat in IIS)

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
BasieP schreef op woensdag 03 oktober 2012 @ 14:21:
Echter wat ik niet snap is waarom hier (zelfs met context switches) iets fout zou kunnen gaan.

@MrBucket:
Ik laat op een bepaalde pagina direct die username zien (als soort van debug).
Hier zien gebruikers soms namen van andere gebruikers staan.
Als dit meer dan eens is gebeurd, lijkt het me zeer onwaarschijnlijk dat het door een context switch komt.

Wordt er niet iets als output caching gebruikt door ASP.NET, dat die het beschreven gedrag veroorzaakt?

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 23:11

Haan

dotnetter

En wat gebeurt er als je de method wijzigt in:
C#:
1
2
3
4
5
6
7
8
9
10
11
public static class Helper  
{ 
    public static GetUserName(IPrincipal user) 
    { 
        if (user != null) 
        { 
            return Regex.Replace(user.Identity.Name, @"(.*?\\)?(.*?)", "$2"); 
        } 
        return "";  //hier is IIS neit goed geconfigt 
    } 
}


?

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Haan schreef op woensdag 03 oktober 2012 @ 14:31:
En wat gebeurt er als je de method wijzigt in:
C#:
1
2
3
4
5
6
7
8
9
10
11
public static class Helper  
{ 
    public static GetUserName(IPrincipal user) 
    { 
        if (user != null) 
        { 
            return Regex.Replace(user.Identity.Name, @"(.*?\\)?(.*?)", "$2"); 
        } 
        return "";  //hier is IIS neit goed geconfigt 
    } 
}


?
en dan aanroepen met HttpContext.Current.User neem ik aan?

goede vraag.
Probleem doet zich bij ons alleen voor in productie, en daar kan ik niet 'even wat proberen'.
Op onze testomgeving krijg ik het probleem niet gereproduceerd.

Vandaar dat ik het graag wil beredeneren. Ik kan geen test maken die eerst fout en dan na een wijziging goed gaat.
Aangezien ik zeker weet dat het in die methode fout gaat wil ik het dus kunnen beredeneren.

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 21:51
BasieP schreef op woensdag 03 oktober 2012 @ 14:36:
[...]

Probleem doet zich bij ons alleen voor in productie, en daar kan ik niet 'even wat proberen'.
Op onze testomgeving krijg ik het probleem niet gereproduceerd.
Dan is de eerste vraag natuurlijk, hoever de testomgeving verschilt van de productieomgeving.

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 23:11

Haan

dotnetter

Vanuit een webpagina wordt de aanroep
C#:
1
2
// User is als property beschikbaar via System.Web.UI.Page
string s = Helper.GetUserName(User);

Dit zou voor zover ik kan beredeneren niet fout mogen gaan.
ThomasG schreef op woensdag 03 oktober 2012 @ 14:42:
[...]
Dan is de eerste vraag natuurlijk, hoever de testomgeving verschilt van de productieomgeving.
Het grote verschil zal het aantal gelijktijdige users zijn ;)

[ Voor 39% gewijzigd door Haan op 03-10-2012 14:43 ]

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Haan schreef op woensdag 03 oktober 2012 @ 14:42:
Vanuit een webpagina wordt de aanroep
C#:
1
2
// User is als property beschikbaar via System.Web.UI.Page
string s = Helper.GetUserName(User);

Dit zou voor zover ik kan beredeneren niet fout mogen gaan.


[...]

Het grote verschil zal het aantal gelijktijdige users zijn ;)
Eens.
Maar dit is nu ook ongeveer wat ik gebouwd heb. Dit gaan we binnenkort installeren in productie.

Daarmee is het probleem wel opgelost (naar alle waarschijnlijkheid).

Wat ik me trouwens nog kan voorstellen is dat na compilatie de code er ongeveer zo uitziet:

code:
1
2
3
4
5
6
if (HttpContext.Current.User != null)
{
string name = HttpContext.Current.User.Identity.Name;
return Regex.Replace(name, @"(.*?\\)?(.*?)", "$2");
}
return "";

Dus dat hij stiekum eerst de variabele uit de HttpContext.Current.User.Identity.Name op de stack zet, en dan vervolgens een contextSwitch doet en aangezien de stack een gedeelde stack is gaat het fout.

Echter zou dan jouw oplossing (Haan) ook fout gaan.
(hij zet dan user.Identity.Name eerst op de stack, en doet dan een ContextSwitch)

Correct me if i'm wrong, maar wat ik begrepen had is het zo dat als je method static is, je de stack deelt. Dat zou betekenen dat je uberhaupt een variabele maakt OF een functie aanroept in een andere functie (de CLR maakt daar een variabele van op de stack) je op je bek gaat.

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 23:11

Haan

dotnetter

Vraagt blijft natuurlijk waarom je in eerste plaats persé die method static wilt hebben?

Je kan het bijv. ook in een base page class stoppen en al je pagina's daarvan laten erven.
Dus zoiets:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class PageBaseWithUsefulExtras : System.Web.UI.Page
{
    protected string Username
    {
        get
        {
            if (User != null)
            {
                string name = User.Identity.Name;
                return Regex.Replace(name, @"(.*?\\)?(.*?)", "$2");
            }
            return string.Empty;
        }
    }
}

[ Voor 51% gewijzigd door Haan op 03-10-2012 15:02 ]

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 20:56
Haan schreef op woensdag 03 oktober 2012 @ 14:58:
Vraagt blijft natuurlijk waarom je in eerste plaats persé die method static wilt hebben?

Je kan het bijv. ook in een base page class stoppen en al je pagina's daarvan laten erven.
Of laden met een DI framework zoals StructureMap

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
@haan.

Ik hoef hem niet persee static. Nogmaals:
Ik heb hem al omgebouwd.

Dit topic is niet om een probleem op te lossen, maar om te bekijken waarom het uberhaupt mis gaat.
Het probleem is al opgelost ;)

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
als ik met IL DASM kijk zie ik het volgende:

  IL_0049:  call       class [System.Web]System.Web.HttpContext [System.Web]System.Web.HttpContext::get_Current()
  IL_004e:  callvirt   instance class [mscorlib]System.Security.Principal.IPrincipal [System.Web]System.Web.HttpContext::get_User()
  IL_0053:  callvirt   instance class [mscorlib]System.Security.Principal.IIdentity [mscorlib]System.Security.Principal.IPrincipal::get_Identity()
  IL_0058:  callvirt   instance string [mscorlib]System.Security.Principal.IIdentity::get_Name()
  IL_005d:  ldstr      "(.*\?\\\\)\?(.*\?)"
  IL_0062:  ldstr      "$2"
  IL_0067:  call       string [System]System.Text.RegularExpressions.Regex::Replace(string,
                                                                                    string,
                                                                                    string)


Ik ben geen expert, maar het lijkt er op dat hij eerst alle parameters van de functie op de stack zet, en dan de functie aanroept (die waarschijnlijk de parameters weer van de stack haalt)
Ik weet alleen niet of in CLR er nog een lock oid omheen gezet wordt..

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Hydra schreef op woensdag 03 oktober 2012 @ 13:56:
[...]
Sowieso kan tussen de HttpContext.Current.User != null check en de regex een context-switch optreden.
Volgens mij niet hoor, HttpContext.Current maakt volgens mij gewoon gebruik van ThreadLocal storage, dus aangezien je op dezelfde thread blijft zou dat geen enkel probleem moeten opleveren. Context switches op de thread/Wisselen van de afhandelende thread zullen allen plaatsvinden tussen verschillende stadia van de processing pipeline.

Maar anders zou het alsnog eenvoudig op te lossen zijn door ene local copy van de HttpContext.Current te maken.

Hoe heb je geconstateerd dat het hier mis gaat? Het zou me niks verbazen als je probleem heel ergens anders zit.

[ Voor 31% gewijzigd door Woy op 03-10-2012 17:08 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Woy schreef op woensdag 03 oktober 2012 @ 16:59:
[...]
Hoe heb je geconstateerd dat het hier mis gaat? Het zou me niks verbazen als je probleem heel ergens anders zit.
Verbaast me dat je de eerste bent die dit zegt ;)

Ik heb een masterpage die eigenlijk vrij rechtsreeks de Helper.GetUserName() functie aanroept en output naar scherm gooit.

Masterpage is per pagina dus per thread. Elke thread maakt dus eigen instantie van masterpage class.
Hierin kan het dus niet fout gaan.
Toch krijgen gebruikers van die masterpage soms een andere username terug.

@Woy,
Je klinkt alsof je er verstand van hebt.

Is het nou zo dat een lokale variabele in een static method van een static class threadsafe gebruikt kan worden?

dus:
C#:
1
2
3
4
5
6
7
8
9
10
11
public static class Helper 
{
    public static GetUserName()
    {
        var hoi = HttpContext.Current;

        //hier een contextSwitch

        return hoi.User.Identity.Name;
    }
}

[ Voor 23% gewijzigd door BasieP op 03-10-2012 17:15 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Yup, die variabele is thread safe, maar dat zegt natuurlijk niet dat het object zelf perse Thread safe is. Maar in deze context zal dat geen problemen opleveren.

Ik geloof er nog steeds niks van dat de methode die je in de startpost hebt getoond je probleem veroorzaakt. Ik denk eerder dat er toch iets met caching is.

Zelfs bij de volgende code zal het IMHO niet fout gaat
C#:
1
2
3
4
5
6
7
8
9
10
11
12
public static class Helper 
{
    public static GetUserName()
    {
        if (HttpContext.Current.User != null)
        {
            Thread.Sleep(10000);
            return Regex.Replace(HttpContext.Current.User.Identity.Name, @"(.*?\\)?(.*?)", "$2");
        }
        return "";  //hier is IIS neit goed geconfigt
    }
}

De thread zal immers pas een nieuwe context toegewezen krijgen op het moment dat dat gedeelte van de asp.net pipeline is afgebroken. Je kunt er bijvoorbeeld niet vanuit gaan dat je PreRender in dezelde thread wordt uitgevoerd als de Render. Maar tijdens bijvoorbeeld de Render stap weet je wel zeker dat jij control op je thread hebt.

[ Voor 57% gewijzigd door Woy op 03-10-2012 17:32 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Woy schreef op woensdag 03 oktober 2012 @ 17:28:
Yup, die variabele is thread safe, maar dat zegt natuurlijk niet dat het object zelf perse Thread safe is. Maar in deze context zal dat geen problemen opleveren.

Ik geloof er nog steeds niks van dat de methode die je in de startpost hebt getoond je probleem veroorzaakt. Ik denk eerder dat er toch iets met caching is.

Zelfs bij de volgende code zal het IMHO niet fout gaat
C#:
1
2
3
4
5
6
7
8
9
10
11
12
public static class Helper 
{
    public static GetUserName()
    {
        if (HttpContext.Current.User != null)
        {
            Thread.Sleep(10000);
            return Regex.Replace(HttpContext.Current.User.Identity.Name, @"(.*?\\)?(.*?)", "$2");
        }
        return "";  //hier is IIS neit goed geconfigt
    }
}

De thread zal immers pas een nieuwe context toegewezen krijgen op het moment dat dat gedeelte van de asp.net pipeline is afgebroken. Je kunt er bijvoorbeeld niet vanuit gaan dat je PreRender in dezelde thread wordt uitgevoerd als de Render. Maar tijdens bijvoorbeeld de Render stap weet je wel zeker dat jij control op je thread hebt.
Je bent de tweede die tegen me zegt dat die code goed (en threadsafe) is.

Nu kan ik echter weinig doen om aan te tonen dat het daar niet aan ligt. Dinsdag gaan we de hotfix uitleveren die ervoor zorgt dat dit stukje code niet als static method maar als instance method werkt. (overerving van Page gemaakt, en hem daarin gezet) Al onze pagina's erven nu over van die class, ipv van Page.

Dit zou alle soorten van threadsafety fouten oplossen.
Mocht het probleem zich nog steeds voordoen dan gaan we aan de omgeving twijfelen. (mede omdat we het op de testomgeving niet kunnen reproduceren)

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Threadsafety draait om het beveiligen van gelijktijdig gebruik van programma state.
Dat een FUNCTIE static is maakt niet uit, het gaat om static of shared STATE (ie, variabelen), die moet je veilig maken. Houd er rekening meer dat een C# class instance shared is tussen alle variabelen die er naar verwijzen :)

Sommige mensen hier denken dat een context-switch iets "evils" is, zitten verkeerd. Context-switches hebben niet direct iets te maken met thread-safety. Threads zijn SPECIFIEK bedoeld om parallel uit te voeren, en threads kunnen dus gewoon dezelfde objecten gebruiken, of er nou context-switches zijn of niet. Het is de taak van de programmeur om:
1) te weten wanneer dat veilig is en
2) zo niet, te synchroniseren (C# heeft het fantastische lock statement daarvoor)

De bovenstaande functie lijkt mij gewoon threadsafe, inzoverre HttpContext threadsafe is. Ik ben verder geen ASP expert, maar ik zie op MSDN over HttpContext: "Any instance members are not guaranteed to be thread safe."

[ Voor 15% gewijzigd door MLM op 03-10-2012 19:36 ]

-niks-


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
MLM schreef op woensdag 03 oktober 2012 @ 19:34:
Houd er rekening meer dat een C# class instance shared is tussen alle variabelen die er naar verwijzen :)
Your point being?
De bovenstaande functie lijkt mij gewoon threadsafe, inzoverre HttpContext threadsafe is. Ik ben verder geen ASP expert, maar ik zie op MSDN over HttpContext: "Any instance members are not guaranteed to be thread safe."
HttpContext.Current is inderdaad threadsafe. En om mensen voor te zijn: Het enigste wat de zin "Any instance members blabla" betekend is dat HttpContext.Current.Items of .Session niet threadsafe zijn (om een paar voorbeelden te noemen).
Wat niet verwonderlijk is.

Nogmaals, HttpContext.Current is inderdaad threadsafe. En ik sluit me ook volledig aan bij de opmerking van Woy. Het probleem zit hem niet in de geleverde code snippet. Waarschijnlijk is het een samenspel van meerdere dingen wat dit probleem veroorzaakt.

Heb je niet gewoon output caching aanstaan.

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
in ieder geval een van de pagina's waarop het mis gaat is een pragma: no-cache...

lijkt me dus geen caching verhaal.

Verder heb ik output caching nergens zelf aangezet, en zou dus uit moeten staan.

trouwens over dat "Any instance members blabla" (sorry Deathraven)

Zou het kunnen dat HttpContext.Current threadsafe is, maar HttpContext.Current.User.Identity.Name niet?

Volgens mijn beredenering niet, omdat HttpContext.Current een instance van de huidige context (dus per thread) teruggeeft.
Toch vraag ik het maar even

[ Voor 45% gewijzigd door BasieP op 03-10-2012 21:26 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
Dat instance members niet threadsafe zijn houd puur in dat als je binnen de afhandeling van een request over meerdere threads gaat zitten rotzooien met bv de Items collectie, dat dit dan niet threadsafe is. Meer niet.

Nee dat klopt het User object is niet threadsafe... maar dat is niet het probleem. Zolang je niet zelf het User object ergens zelf gaat bijhouden maar iedere keer via de HttpContext.Current aanspreekt is er geen probleem.

Acties:
  • 0 Henk 'm!

  • eek
  • Registratie: Februari 2001
  • Laatst online: 06-04-2020

eek

@MagickNET

Ik vraag me af of je de echte oorzaak wel hebt gevonden. In je openingspost zeg je dat het hebt opgelost en het nu goed gaat. Maar je zegt ook dat je het probleem niet kan reproduceren. Hoe heb je dan kunnen controleren dat het nu goed gaat?

Bewaar je het resultaat van 'Helper.GetUserName()' nog ergens?

Skill is when luck becomes a habit.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
MLM schreef op woensdag 03 oktober 2012 @ 19:34:
De bovenstaande functie lijkt mij gewoon threadsafe, inzoverre HttpContext threadsafe is. Ik ben verder geen ASP expert, maar ik zie op MSDN over HttpContext: "Any instance members are not guaranteed to be thread safe."
Dat is inderdaad wat ik bedoelde met het feit dat het object zelf waarschijnlijk niet Thread safe is. Maar het object wordt ook maar in één thread gebruikt, en tevens alleen read-only. De Principal wordt immers al aan het begin van de processing pipeline gezet, en niet meer veranderd, dus al zou je daar met meerdere threads tegelijk op lezen is dat nog geen probleem.

De HttpContext.Current is een ThreadLocal variabele, die door de ASP.NET stack gezet wordt voordat jij control krijgt, en zal dus ook zeker geen probleem vormen.
BasieP schreef op woensdag 03 oktober 2012 @ 20:24:
in ieder geval een van de pagina's waarop het mis gaat is een pragma: no-cache...
Dat gaat over client-side caching, en dat zal hier het probleem niet zijn. Immers kan een client natuurlijk niet de username van een andere user cachen ;)
lijkt me dus geen caching verhaal.

Verder heb ik output caching nergens zelf aangezet, en zou dus uit moeten staan.
Toch denk ik dat er ergens serverside (partial) caching aan staat. Of zit er misschien ergens een (verkeerd geconfigureerde) proxy tussen?
trouwens over dat "Any instance members blabla" (sorry Deathraven)

Zou het kunnen dat HttpContext.Current threadsafe is, maar HttpContext.Current.User.Identity.Name niet?

Volgens mijn beredenering niet, omdat HttpContext.Current een instance van de huidige context (dus per thread) teruggeeft.
Toch vraag ik het maar even
Zoals ik hierboven aangeef is is HttpContext.Current inderdaad geen enkel probleem zoals je hem in je voorbeeld gebruikt. HttpContext.Current.User.Identity.Name zou in theorie inderdaad thread unsafe kunnen zijn. Echter wordt de principal niet op de HttpContext niet geupdate door de ASP.NET code terwijl de pagina gerenderd wordt, immers zal elk request zijn eigen HttpContext hebben. Aangezien het dus alleen read-only is zal het geen problemen op kunnen leveren.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Toch denk ik dat er ergens serverside (partial) caching aan staat. Of zit er misschien ergens een (verkeerd geconfigureerde) proxy tussen?
Nu is dit misschien wel het geval (er zit een apache met hproxy tussen die ik niet zelf geconfigureerd heb of waarvan ik geen kennis heb.
Echter draait datzelfde ding voor een stuk of 10 grote applicaties (o.a. ons intranet) en hier gaat het blijkbaar altijd goed.
De constructie schijnt volgens de maker ook door twitter gebruikt te worden dus het concept is proven. Implementatie is wellicht verkeerd, maar dan zou je zeggen dat het vaker fout moet gaan.

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • __fred__
  • Registratie: November 2001
  • Laatst online: 19:39
Pragma no-cache is een meta tag en proxies houden daar vaak geen rekening mee.

Ik zou een stukje gaan lezen over caching en http headers, want daar zit vrijwel zeker je probleem.

Zoiets:

http://www.mnot.net/cache_docs/

Overigens, ik weet niet of het een applicatie is die aan internet hangt, maar een applicatie waar je moet inloggen en die geen SSL gebruikt is natuurlijk een doodzonde. HTTPS verkeer wordt nooit gecacht door een proxy, dus dit betekent dat je probleem of elders ligt, of je geen SSL gebruikt en dan gaan je wachtwoorden in plain text over internet. Niet doen dus.

[ Voor 44% gewijzigd door __fred__ op 05-10-2012 10:57 . Reden: Opmerking over SSL ]


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Nou ik heb vandaag van een van mijn gebruikers (van wie ik de hostfile had aangepast, zodat hij niet door de proxy ging, maar direct naar de webserver) dat hij het probleem ook heeft gehad.

Dit betekend dat ik de proxy uitgesloten heb.
Aangezien wij hier (helaas) company wide IE8 gebruiken werken pragma headers ook prima, dus daar ligt het ook niet aan.

Morgen heb ik de installatie van de 'fix' waarin ik dus niet meer de public static method aanroep, maar een instance method. (die hetzelfde doet)
(niet naar, maar wel als het voorbeeld van Haan. zie: Haan in "\[ASP.Net] asp.net threadsafe maken")

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

BasieP schreef op woensdag 03 oktober 2012 @ 15:03:
@haan.

Ik hoef hem niet persee static. Nogmaals:
Ik heb hem al omgebouwd.

Dit topic is niet om een probleem op te lossen, maar om te bekijken waarom het uberhaupt mis gaat.
Het probleem is al opgelost ;)
Hoe weet je of het probleem is opgelost als je het niet kan reproduceren?
Ik ben het met Woy eens, ik geloof niet dat je code het probleem is. Maar dat er inderdaad ergens server-side gecached word.
Ik heb nog nooit threading issues gehad met HttpContext.Current (zal ook lekker nutteloze api zijn als dat wel het geval was). Ook niet in static helper methodes.

Ducati: making mechanics out of riders since 1946


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
TheNameless schreef op maandag 08 oktober 2012 @ 11:21:
[...]

Hoe weet je of het probleem is opgelost als je het niet kan reproduceren?
Ik ben het met Woy eens, ik geloof niet dat je code het probleem is. Maar dat er inderdaad ergens server-side gecached word.
Ik heb nog nooit threading issues gehad met HttpContext.Current (zal ook lekker nutteloze api zijn als dat wel het geval was). Ook niet in static helper methodes.
Daar heb je gelijk, ik heb wijzigingen gemaakt. Daarmee hoop ik dat het probleem is opgelost.
Ik kan het niet reproduceren, maar daar werk ik ondertussen ook aan. (ben nu bezig met een meer productie-like testscenario te verzinnen)

Echter is het lastig om te concluderen dat het is opgelost zonder dat het gereproduceerd is.

Ik wil jullie allemaal geloven wanneer je zegt dat het niet aan dat stukje code kan liggen, maar voor client-side caching moet ik dingen gedaan hebben, en dat heb ik voor zover ik weet niet.

Dus als iemand mij kan vertellen hoe zoiets automagisch werkt dan hoor ik het graag, maar tot die tijd sluit ik die optie gewoon uit.

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

Ik weet niet precies om wat voor applicatie het gaat, maar dit soort issues hebben wij ook wel eens gehad op het werk met een multi-tenant applicatie, waarin je als user zijnde je klanten kan beheren.

Deze applicatie draait onder 1 domein en als je dan niet zorgt dat je URLs verschillen per klant, dan kan je dit soort issues krijgen. Zowel client-side (vooral IE wilt nog al eens agressief cachen) als op de server.
Op de server hebben we dit opgelost door een custom implementatie van GetVaryByCustomString (maar dat is een heel ander verhaal).

Maar nogmaals, misschien is bovenstaande scenario wel helemaal niet van toepassing op jou applicatie.

Ducati: making mechanics out of riders since 1946


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
TheNameless schreef op maandag 08 oktober 2012 @ 11:46:
Deze applicatie draait onder 1 domein en als je dan niet zorgt dat je URLs verschillen per klant, dan kan je dit soort issues krijgen. Zowel client-side (vooral IE wilt nog al eens agressief cachen) als op de server.
Op de server hebben we dit opgelost door een custom implementatie van GetVaryByCustomString (maar dat is een heel ander verhaal).
Dat zou toch niet de bedoeling moeten zijn. ik weet dat IE6 moeite had met caching, en dat een timestamp aan een requests toevoegen uit kan maken, echter mag dit serverside echt niet uitmaken. In jou geval komt het probleem misschien niet meer voor (doordat je url's uniek maakt) maar is niet opgelost.

Verder sluit ik clientside caching gewoon uit, omdat ik gewoon zie dat ik 200 OK's terug krijg, en dus de client echt bij de server is langsgegaan.

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

BasieP schreef op maandag 08 oktober 2012 @ 11:50:
[...]

Dat zou toch niet de bedoeling moeten zijn. ik weet dat IE6 moeite had met caching, en dat een timestamp aan een requests toevoegen uit kan maken, echter mag dit serverside echt niet uitmaken. In jou geval komt het probleem misschien niet meer voor (doordat je url's uniek maakt) maar is niet opgelost.

Verder sluit ik clientside caching gewoon uit, omdat ik gewoon zie dat ik 200 OK's terug krijg, en dus de client echt bij de server is langsgegaan.
Misschien heb ik mijn voorbeeld wat te simpel voorgeschoteld, het zit wat ingewikkelder in elkaar.
En het was in ieder geval wel de juiste oplossing voor ons probleem :)

Ik probeer alleen je wat richting te geven over waar het misschien aan kan liggen.

Ducati: making mechanics out of riders since 1946


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
Nou update dan maar:

inmiddels zijn we er achter dat het in ieder geval alleen maar voorkomt wanneer de gebruiker via de loadbalancer gaat.
Tevens valt op dat elke keer dat het zo is, je ook op een andere server zit. (dus dat de loadbalancer je geswichedt heeft)

Nu zou de loadbalancer je per sessie op dezelfde server moeten laten, maar buiten dat vind ik dat de applicatie daar niet fout op mag gaan.

Nu heb ik twee theoriën die ik graag aan jullie voor wil leggen:

1. ASP.NET/IIS generatie van sessie_ID is verre van uniek. En zodoende is de kans dat wanneer je op een andere server komt jouw sessie ook op die andere machine bestaat (van een andere gebruiker) heel groot

2. ASP.NET cached stiekum de username van de door IIS in AD controlleerde gebruiker in de sessie, waardoor je bij een tweede keer opvragen van de username eigenlijk niet direct naar IIS -> AD gaat, maar gewoon in de cache kijkt.


Wanneer die twee stelling waar zijn heb ik in theorie mijn probleem opgelost. Het zou dan namelijk zo zijn dat
1. de loadbalancer je 'zomaar' naar een andere server gooit.
2. de server jouw sessie kent (want je sessie id komt voor) maar dat hij denkt dat je iemand anders bent
3. de server de username van die andere gebruiker uit zijn session (!) based cache haalt
4. ik met die username naar de DB ga en verkeerde gegevens ophaal


Echter is er 1 bezwaar tegen dit hele verhaal, en dat is dat ik het heeeeeeel raar vind dat IIS zo vaak dezelfde sessie ID's uitgeeft.
Weet iemand hoe dat nummer gegenereerd wordt? Ik kan daar bar weinig over vinden op internet namelijk.
Als het op basis van hele uren en een volgnummer werkt kan ik me voorstellen dat ie nummers dubbel uitgeeft.


edit:
owja ik wil nog even duidelijk maken dat ik weet dat er oplossingen zijn voor dit probleem. Dit zouden dingen als SQL server en stateserver etc. zijn.
Echter wil ik eigenlijk eerst bevestigt zien dat het daadwerkelijk om dit probleem gaat. Ik wil dus met zekerheid tegen mijn baas kunnen zeggen dat we weten hoe het komt.
Niet een dure SQL server neerzetten en projectarchitectuur wijzigen om vervolgens achter te komen dat het niets heeft geholpen.

[ Voor 11% gewijzigd door BasieP op 25-10-2012 13:19 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 23:11

Haan

dotnetter

Ah, load balancing! Altijd een feest! :X
Je kan daar zelf een hoop van vinden wat het wel/niet zou moeten doen, maar feit is dat je in dat geval niet de default voor Sessions kunt gebruiken. Je kan inderdaad kiezen tussen een state server of 'gewoon' een database pakken, ik heb alleen ervaring met het laatste, wat ook eigenlijk zeer simpel is. Het enige dat je daarvoor feitelijk nodig hebt, is een database die door alle web servers benaderd kan worden. Configuratie kan je gewoon via een grafische tooltje doen dat standaard al op je web server (aspnet_regsql.exe, wat je ook kunt gebruiken voor het creëren van een standaard Membership database).
Mocht je ooit een website gaan hosten in Azure loop je tegen precies hetzelfde probleem aan, omdat je dan ook altijd minstens 2 servers hebt (of 1, maar dan val je buiten de SLA van Microsoft)

Zowel een state server, als een sql server oplossing zijn in te stellen zonder 1 regel code te wijzigen, omdat je dit configureert in de web.config.

Wat betreft het uitgeven van dezelfde Session ID's: dat vind ik ook vreemd dat dat blijkbaar regelmatig gebeurt, maar ik heb verder ook geen idee hoe die dingen gegenereerd worden..

[ Voor 8% gewijzigd door Haan op 25-10-2012 14:19 ]

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Haan schreef op donderdag 25 oktober 2012 @ 14:18:
Zowel een state server, als een sql server oplossing zijn in te stellen zonder 1 regel code te wijzigen, omdat je dit configureert in de web.config.
Dat is alleen zo zolang alle items die in je Session gestopt worden Serializable zijn! Maar idd een stateserver of db base sessions zijn zeer eenvoudig te configureren.

Verder worden de Session Id's zover ik weet gegenereerd d.m.v. de RNGCryptoServiceProvider. Het zou best kunnen dat die ergens een timestamp als seed gebruikt, en dus is het niet vreemd als er een keer duplicate session id's komen. Maar dat is natuurlijk iets wat je redelijk eenvoudig kan ontdekken door gewoon de remote host en het session id ergens te loggen, en dat na te kijken op het moment dat het een keer mis gaat.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
mja ik zit momenteel nog even te twijfelen of ik de applicatie sessieloos kan maken..

Enige dat ik nu opsla in sessie is de groepen waar de gebruiker in zit (in AD) zodat ik autorisatie kan doen.

Als ik een static Dictionary maak die op basis van username die gegevens beheerd ben ik er ook, en hoef ik dus geen sessie's te gebruiken.

Binnen ons bedrijf is een architectuurwijziging (toevoegen van stateserver of sqlserver) niet zo 123 gebeurd.

Andere mogelijkheid is om zelf mij sessie ID te gaan genereren, en die te laten bestaan uit de servernaam en dan een lange random string (guid oid). Op die manier zijn je sessies dus opeens over servers heen uniek, en hoef ik verder niets aan de archtectuur te wijzigen.

trouwens wordt dat laaste door iedereen afgeraden en ik snap nog niet helemaal waarom. Als ik een guid vooraf laat gaan door een servernaam en een tijd en daar een lange sha2/3 hash ban maak ben ik toch super veilig? (en traag)

[ Voor 14% gewijzigd door BasieP op 25-10-2012 15:56 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
BasieP schreef op donderdag 25 oktober 2012 @ 15:44:
mja ik zit momenteel nog even te twijfelen of ik de applicatie sessieloos kan maken..

Enige dat ik nu opsla in sessie is de groepen waar de gebruiker in zit (in AD) zodat ik autorisatie kan doen.

Als ik een static Dictionary maak die op basis van username die gegevens beheerd ben ik er ook, en hoef ik dus geen sessie's te gebruiken.
Gebruik niet een static dictionary en gebruik geen sessie; gebruik gewoon een rollende cache. Als de relevante AD rechten van een bepaalde gebruiker nog niet in de cache zitten worden ze gewoon eerst opgehaald en vervangen daarbij (indien de cache capaciteit overschreden wordt) de langst niet gebruikte set.

Werkt ongeacht je op server A of B bezig bent of tussen beide servers aan het heen en weer stuiteren bent.

Uiteraard is het hierbij wel zaak om te zorgen dat een bepaalde set rechten een maximale levensduur krijgen voordat ze geforceerd geflusht worden en opnieuw opgehaald. Anders blijft je cache niet in sync met de werkelijke situatie op de AD.

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
R4gnax schreef op donderdag 25 oktober 2012 @ 20:22:
[...]


Gebruik niet een static dictionary en gebruik geen sessie; gebruik gewoon een rollende cache. Als de relevante AD rechten van een bepaalde gebruiker nog niet in de cache zitten worden ze gewoon eerst opgehaald en vervangen daarbij (indien de cache capaciteit overschreden wordt) de langst niet gebruikte set.

Werkt ongeacht je op server A of B bezig bent of tussen beide servers aan het heen en weer stuiteren bent.

Uiteraard is het hierbij wel zaak om te zorgen dat een bepaalde set rechten een maximale levensduur krijgen voordat ze geforceerd geflusht worden en opnieuw opgehaald. Anders blijft je cache niet in sync met de werkelijke situatie op de AD.
mja dat wordt dus een static dictionary ;)
Ding moet static zijn omdat je anders per request cached (en das vrij nutteloos) en een dictionary omdat die gewoon rete snel zoekt.

Het verwijderen van het minst relevante cache record is een dure operatie (zeker ivm locking), dus dat ga ik niet voor elke request doen.
Ik dacht meer aan iets als:
Per keer dat ik een cacherecord toevoeg kijk ik naar het aantal records in de cache als die de treshold heeft overschreden ga ik een schoningsjob draaien die alle te oude cache records weggooit.

Te oud zal te maken hebben met de session lifetime op die server (liefst even lang)
En als ik dan nog niet aan mijn treshold zit ga ik de 10% oudste records verwijderen.

Hierdoor hoef ik bij mijn volgende request niet weer direct te schonen.
Mocht nou zo zijn dat ik dan nog te vaak schoon ga ik de treshold verhogen met 10%. Wanneer ik dat precies ga doen moet ik nog even over nadenken. Wellicht maak ik dat een handmatige stap.


Kan ik mooi weer een performance counter maken van het aantal keer per gebruiker dat ie 'opnieuw' naar ldap moet, of de aantal cache bevragingen per seconde oid.

[ Voor 4% gewijzigd door BasieP op 25-10-2012 23:54 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ga nou niet zelf het wiel opnieuw uitvinden ;)
MSDN: Cache Class (System.Web.Caching)
3. de server de username van die andere gebruiker uit zijn session (!) based cache haalt
Dat lijkt me trouwens erg sterk. De authenticatie maakt zeker weten geen gebruik van de session, dus als dat het geval zou zijn dan moet het toch iets in je eigen code zijn.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
@Woy:
die link van caching ga ik zeker even goed lezen
Waarom zit ie trouwens in System.Web?
ding heeft toch niet persee iets met web te maken?


Verder kan ik niet zo veel fout doen.
Ik roep alleen HttpContext.Current.User.Identity.Name aan.
Dit gaat alleen fout als de loadbalancer je net van node heeft geswiched... lijkt me dan niet echt een fout in mijn code .. :s

[ Voor 14% gewijzigd door BasieP op 28-10-2012 13:21 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
BasieP schreef op zondag 28 oktober 2012 @ 13:06:
Waarom zit ie trouwens in System.Web?
vziw gaat de caching layer via IIS als IIS aanwezig is.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
Grijze Vos schreef op maandag 29 oktober 2012 @ 13:38:
[...]

vziw gaat de caching layer via IIS als IIS aanwezig is.
Say what? Nog niet bekant.
Lees dat linkje van Woy maar eens door ;)

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Er is overigens ook een System.Runtime.Caching namespace die niet dependant is op de System.Web namespace, die bied vergelijkbare functionaliteit.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
D-Raven schreef op maandag 29 oktober 2012 @ 14:10:
[...]
Say what? Nog niet bekant.
Lees dat linkje van Woy maar eens door ;)
Gedeeltes van de cache gaan inderdaad via IIS (static content, o.a.) en andere gedeeltes haken zo vroeg op de managed pipeline van ASP.NET in dat je het net zo goed nog als onderdeel van de Hosted Web Core (de kern waarop zowel IIS als IIS Express gebouwd zijn) kunt zien. Check anders maar eens even het AuthorizeAttribute in de open-source ASP.NET MVC broncode. Sla het stukje code dat specifiek is voor het afhandelen van authorisatie in de context van output caching er maar eens op na.

Het zou heel goed kunnen dat als je System.Web.Cache met ILSpy o.i.d. open breekt er nog zware dependencies zijn waar men (al dan niet via reflection) ten dele probeert gebruik te maken van zaken in de Hosted Web Core (of semi-compatible implementaties zoals Cassini).

Er staat tenslotte op diezelfde pagina niet voor niets:
The Cache class is not intended for use outside of ASP.NET applications. It was designed and tested for use in ASP.NET to provide caching for Web applications. For other types of applications, such as console applications or Windows Forms applications, use the ObjectCache class.

Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

Ik snap het niet helemaal meer. Je hebt problemen met HttpContext.Current.User, maar dat hoeft verder toch niet met je sessie te maken te hebben?
Voor zo ver ik weet word deze gezet aan de hand van je ASPXAUTH cookie. En niet je SessionId cookie. (als je Forms Authentication gebruikt i.s.m cookies)

Of ben ik in de war?

[ Voor 9% gewijzigd door TheNameless op 29-10-2012 22:13 ]

Ducati: making mechanics out of riders since 1946


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
R4gnax schreef op maandag 29 oktober 2012 @ 20:26:
[...]


Gedeeltes van de cache gaan inderdaad via IIS (static content, o.a.) en andere gedeeltes haken zo vroeg op de managed pipeline van ASP.NET in dat je het net zo goed nog als onderdeel van de Hosted Web Core (de kern waarop zowel IIS als IIS Express gebouwd zijn) kunt zien. Check anders maar eens even het AuthorizeAttribute in de open-source ASP.NET MVC broncode. Sla het stukje code dat specifiek is voor het afhandelen van authorisatie in de context van output caching er maar eens op na.

Het zou heel goed kunnen dat als je System.Web.Cache met ILSpy o.i.d. open breekt er nog zware dependencies zijn waar men (al dan niet via reflection) ten dele probeert gebruik te maken van zaken in de Hosted Web Core (of semi-compatible implementaties zoals Cassini).

Er staat tenslotte op diezelfde pagina niet voor niets:

[...]
Wat Grijze Vos impliceert is dat als je gebruik maakt van het Cache object in asp.net dat deze dan via IIS gaat. Dat geloof ik niet. Dit klopt niet.
Als je zegt dat er onderdelen in de system.web.caching namespace ook gebruikt worden door IIS. Dat geloof ik best. Al kan ik hier momenteel geen enkel bewijs voor vinden. Als in, de documentatie zegt hier niks over.

Uiteindelijk is het Cache object niks meer dan een fancy hash table based cache met extra's. De reden dat die opmerking op MSDN staat is puur vage geblabla wat neerkomt op "we do not officially support this".

Hier is trouwens ook wat hierover te vinden. En daar staat letterlijk:
The ASP.NET cache object is located in the System.Web namespace, and because it is a generic cache implementation, it can be used in any application that references this namespace.

Acties:
  • 0 Henk 'm!

  • __fred__
  • Registratie: November 2001
  • Laatst online: 19:39
Het blijft echt gissen wat voor config je hebt staan he op deze manier. Welke vorm van load balancing hangt ervoor. Is het Round Robin DNS, is het een load balancing cluster, is het Application Request Routing, heb je soms een 3rd party load balancer?

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Op deze manier is het niet echt handig, want er lopen twee topics door elkaar. Deze ga ik sluiten, er kan verder gegaan worden in het andere topic: \[asp.net] ntlm proxies loadbalancers sessies

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1

Dit topic is gesloten.