Archives

Archives / 2011 / January
  • Web.Config is Cached

    There was a question from a student over on the Asp.Net forums about improving site performance. The concern was that every time an app setting was read from the Web.Config file, the disk would be accessed. With many app settings and many users, it was believed performance would suffer.

    Their intent was to create a class to hold all the settings, instantiate it and fill it from the Web.Config file on startup. Then, all the settings would be in RAM. I knew this was not correct and didn't want to just say so without any corroboration, so I did some searching.

    Surprisingly, this is a common misconception. I found other code postings that cached the app settings from Web.Config. Many people even thanked the posters for the code.

    In a later post, the student said their text book recommended caching the Web.Config file.

    OK, here's the deal. The Web.Config file is already cached. You do not need to re-cache it.

    From this article http://msdn.microsoft.com/en-us/library/aa478432.aspx

    It is important to realize that the entire <appSettings> section is read, parsed, and cached the first time we retrieve a setting value. From that point forward, all requests for setting values come from an in-memory cache, so access is quite fast and doesn't incur any subsequent overhead for accessing the file or parsing the XML.

    The reason the misconception is prevalent may be because it's hard to search for Web.Config and cache without getting a lot of hits on how to setup caching in the Web.Config file.

    So here's a string for search engines to index on: "Is the Web.Config file Cached?"

    A follow up question was, are the connection strings cached?

    Yes. http://msdn.microsoft.com/en-us/library/ms178683.aspx

    At run time, ASP.NET uses the Web.Config files to hierarchically compute a unique collection of configuration settings for each incoming URL request. These settings are calculated only once and then cached on the server.

    And, as everyone should know, if you modify the Web.Config file, the web application will restart.

    I hope this helps people to NOT write code!  

    Steve Wellens

  • Passing Strings by Ref

    Humbled yet again…DOH! No matter how much experience you acquire, no matter how smart you may be, no matter how hard you study, it is impossible to keep fully up to date on all the nuances of the technology we are exposed to. There will always be gaps in our knowledge: Little 'dead zones' of uncertainty. For me, this time, it was about passing string parameters to functions. I thought I knew this stuff cold. First, a little review...

    Value Types and Ref

    Integers and structs are value types (as opposed to reference types). When declared locally, their memory storage is on the stack; not on the heap. When passed to a function, the function gets a copy of the data and works on the copy. If a function needs to change a value type, you need to use the ref keyword.  Here's an example:

        // ---- declaration -----------------
     
        public struct MyStruct
        {
            public string StrTag;
        }
     
        // ---- functions -----------------------
     
        void SetMyStruct(MyStruct myStruct)     // pass by value
        {
            myStruct.StrTag = "BBB";
        }
     
        void SetMyStruct(ref MyStruct myStruct)  // pass by ref
        {
            myStruct.StrTag = "CCC";
        }
     
        // ---- Usage -----------------------
     
        protected void Button1_Click(object sender, EventArgs e)
        {
            MyStruct Data;
            Data.StrTag = "AAA";
     
            SetMyStruct(Data);
            // Data.StrTag is still "AAA"
     
            SetMyStruct(ref Data);
            // Data.StrTag is now "CCC"
        }

    No surprises here. All value types like ints, floats, datetimes, enums, structs, etc. work the same way.

    And now on to...

    Class Types and Ref

        // ---- Declaration -----------------------------
     
        public class MyClass
        {
            public string StrTag;
        }
     
        // ---- Functions ----------------------------
     
        void SetMyClass(MyClass myClass)  // pass by 'value'
        {
            myClass.StrTag = "BBB";
        }
     
        void SetMyClass(ref MyClass myClass)   // pass by ref
        {
            myClass.StrTag = "CCC";
        }
     
        // ---- Usage ---------------------------------------
     
        protected void Button2_Click(object sender, EventArgs e)
        {
            MyClass Data = new MyClass();
            Data.StrTag = "AAA";
     
            SetMyClass(Data);  
            // Data.StrTag is now "BBB"
     
            SetMyClass(ref Data);
            // Data.StrTag is now "CCC"
        }
     

    No surprises here either. Since Classes are reference types, you do not need the ref keyword to modify an object. What may seem a little strange is that with or without the ref keyword, the results are the same: The compiler knows what to do.

    So, why would you need to use the ref keyword when passing an object to a function?

    Because then you can change the reference itself…ie you can make it refer to a completely different object. Inside the function you can do: myClass = new MyClass() and the old object will be garbage collected and the new object will be returned to the caller.

    That ends the review. Now let's look at passing strings as parameters.

    The String Type and Ref

    Strings are reference types. So when you pass a String to a function, you do not need the ref keyword to change the string. Right? Wrong. Wrong, wrong, wrong.

    When I saw this, I was so surprised that I fell out of my chair. Getting up, I bumped my head on my desk (which really hurt). My bumping the desk caused a large speaker to fall off of a bookshelf and land squarely on my big toe. I was screaming in pain and hopping on one foot when I lost my balance and fell. I struck my head on the side of the desk (once again) and knocked myself out cold. When I woke up, I was in the hospital where due to a database error (thanks Oracle) the doctors had put casts on both my hands. I'm typing this ever so slowly with just my ton..tong ..tongu…tongue.

    But I digress. Okay, the only true part of that story is that I was a bit surprised.

    Here is what happens passing a String to a function.

        // ---- Functions ----------------------------
     
        void SetMyString(String myString)   // pass by 'value'
        {
            myString = "BBB";
        }
     
        void SetMyString(ref String myString)  // pass by ref
        {
            myString = "CCC";
        }
     
        // ---- Usage ---------------------------------
     
        protected void Button3_Click(object sender, EventArgs e)
        {
            String MyString = "AAA";
     
            SetMyString(MyString);
            // MyString is still "AAA"  What!!!!
     
            SetMyString(ref MyString);
            // MyString is now "CCC"
        }

    What the heck. We should not have to use the ref keyword when passing a String because Strings are reference types. Why didn't the string change? What is going on?  

    I spent hours unssuccessfully researching this anomaly until finally, I had a Eureka moment:

    This code:

    String MyString = "AAA";

    Is semantically equivalent to this code (note this code doesn't actually compile):

    String MyString = new String();

    MyString = "AAA";

    Key Point: In the function, the copy of the reference is pointed to a new object and THAT object is modified. The original reference and what it points to is unchanged.

    You can simulate this behavior by modifying the class example code to look like this: 

        void SetMyClass(MyClass myClass)  // call by 'value'
        {
            //myClass.StrTag = "BBB";
            myClass = new MyClass();
            myClass.StrTag = "BBB";
        }

    Now when you call the SetMyClass function without using ref, the parameter is unchanged...just like the string example. 

    I hope someone finds this useful.

    Steve Wellens