C# static variables persisting through vs2012 sessions, static variables NOT initializing correctly on re-run.

public static string s = "NOT initialized"; //my default value
s = "Initialized";

Open in new window

VS 2012, What I am seeing is;

Start Debugging(F5)
Stop Debugging (Shift+F5)
Start Debugging(F5) //not continue

s still equals "Initialized" when I expect it to equal "NOT initialized".

Why is this and how do I make my static variables re-initialize each time I "run" my code.

ps: This does not happen if I change anything in the code and rebuild it.

Thank You
Sam
SamCashAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Najam UddinCommented:
As per Jon Skeet,
"Very little is guaranteed about the behaviour of static variable initializers when there's no static constructor. Indeed, you can even create instances of classes without the static variable initializers being invoked! When you're using a debugger, the CLR does all kinds of things differently (particularly around JITting)"

Using a static constructor is probably the best way of giving you more predictable initialization behaviour.
0
SamCashAuthor Commented:
Najam uddin,

Thanks much.  I tried to use the constructor (failed) but want to try again with more knowledge...

The reason I failed was I could not figure out where to instantiate an object of the class before anything else ran, in other words what which page runs first.  I have read on this "singleton" pattern, I think I can attempt to instantiate it in all the required places and  only the first one will execute, setting my default properties. On each run.  My fear is the static class will still be instantiated on re-run.  I am trying to test this now.

Please if you have better solution or comment on this approach or...

Kind Regards
Sam

public class ResetConnectStringToDefault //Singleton
    {
        private static ResetConnectStringToDefault instance; //declare var instance
        private ResetConnectStringToDefault() //do class initialization stuff
        {
            // run set the defaults
        }
        public static ResetConnectStringToDefault Instance
        {
            get
            {
                if (instance == null)
                    instance = new ResetConnectStringToDefault();
                return instance;
            }
        }
        public static bool TriggerReset
        {
            // I do not have access for "new ResetConnectStringToDefault" due to protection level, so maybe if I access the public method it will trigger the constructor the first time??
        }
    }

Open in new window

0
Najam UddinCommented:
Did you check static constructor

Also "My fear is the static class will still be instantiated on re-run" . Dont you want it to reset on re run?
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

käµfm³d 👽Commented:
...when I expect it to equal "NOT initialized".
Why do you expect this?
0
SamCashAuthor Commented:
Najam uddin,

Thanks again, static constructor seems to be working in my test snippet, I am implementing it now into my project, I am pretty sure it will solve my issue.

Yes I want it to reset on re run, poor English on my part.

Kind Regards
Sam
0
SamCashAuthor Commented:
käµfm³d 👽,

...because I ran the program again, so I expected
public static string s = "NOT initialized"; //my default value

Open in new window

to be run and initialize again, to Not Initialized, later it gets Initialized to the proper value dependent on where the code is being run.

I see I should have used
public static string s = "Set to default"; //my default value

Open in new window

and
 s = "Set to run";

Open in new window

.  That would have made a much clearer question.  I would have expected it to be "Set to Default" instead of persisting at "Set to run"

Thanks
Sam
0
käµfm³d 👽Commented:
to be run and initialize again, to Not Initialized, later it gets Initialized to the proper value dependent on where the code is being run.
That is exactly what happens. A static variable is only going to retain its value while the program is running.. Once your program terminates, it is unloaded from memory by the system--all of it: static, non-static, and otherwise. The next time you run the application, it's as if you've never run it. Programs don't just sit in memory. Your initialization code runs every time you start the application. Whether or not the variable's value gets changed to something else is dependent on how your code is written.
0
käµfm³d 👽Commented:
P.S.

Perhaps, since this is a web application, what could be happening is that you have a build error in your code, but you might be dismissing the dialog that pops up and prompts you to continue anyway. In such a case what you are seeing is the last successful build that has already been loaded into IIS Express and started by the debugger. In such an instance, your application never actually terminated--it's been running in IIS Express the entire time.
0
SamCashAuthor Commented:
käµfm³d 👽,

With respect Savant, from newbe,  If you test the small snippet with vs2012 you will see the static variable persists between debug sessions of F5 and Shift+F5 and F5 again, break at breakpoint it persists the value from the prior run and does not go back to the default value.  

I am in an asp.net webpage environment.  I read that the static variables persists while the app domain is live?  Although I do not understand app domain, maybe IIS is the app domain??  

I am persisting this question as I want to understand and maybe help someone else with the same confusion.

Kindest Regards
Sam
0
SamCashAuthor Commented:
käµfm³d 👽,

Just got your ps...

I have done it 50 + times.  I am familiar with the last successful build dialog, and always "NO" get my build errors fixed and then run again...

Thanks Much
Sam
0
käµfm³d 👽Commented:
I read that the static variables persists while the app domain is live?
Correct.

maybe IIS is the app domain
IIS creates an app domain and loads your app into it, yes.
0
käµfm³d 👽Commented:
With respect, you haven't given us enough information. You've simply supplied two lines of code, told us there is a problem, but haven't shown us how you actually implemented the lines of code. As I mentioned above, how the variable's value gets adjusted is going to depend on the way you structure your logic.

For example, in the project linked below I have defined your static variable on the HomeController. There are two links on the Index view. One link passed a value of true to the Test action, and the other link passes a value of false. This value is received by the flag parameter within the Test action. Within the Test action, the flag determines whether or not the static variable's value is overwritten. If you click the link which passes false, then you will see the "default" value. You will continue to see this value no matter how many times you click the "false" link. Once you click the "true" link, only then will the default value be overwritten. After clicking that link, clicking the "false" link still shows the updated value.

Now, if you stop the application and restart it (via F5), then you will observe the same exact behavior:  clicking the "false" link first will show the default; clicking the "true" link overwrites the value.

Sample Project
https://filedb.experts-exchange.com/incoming/ee-stuff/8430-28803339.zip

Video Demonstration
https://filedb.experts-exchange.com/incoming/ee-stuff/8431-Example.mp4
0
SamCashAuthor Commented:
Najam uddin,
käµfm³d 👽,

Sorry for not being verbose at the beginning, I thought it was simple.  Below is a small sample demonstrating my issue.  I moved to a static class and used the static constructor as Najam uddin suggested.

The following test procedure demonstrates old static values persisting on subsequent "Run[s]".

1. F5 Run, the label = "Default", ...Expected
2. click button, the label = "Not Default", ...Expected
3. shift + F5 Stop,

F5 Run, the label = "Not Default", ...NOT Expected, I expected "Default". I thought it should have run the constructor, but its instance must still be persisting so it did not??

This behavior persists if I close the browser
This behavior does not persists if
1. edit any code
2. rebuild
3. stop IIS
4. stop and relaunch vs2012

Thank You for sharing your experience and helping me solve this issue.
Sam

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Scratch_Debug.aspx.cs" Inherits="WebApplication1.Debug.Scratch_Debug" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Label ID="lblStaticTest" runat="server" Text="lblStaticTest"></asp:Label><br />
        <asp:Button ID="btnSetS" runat="server" Text="btnSetS" OnClick="btnSetS_Click" />
    </div>
    </form>
</body>
</html>

Open in new window

namespace WebApplication1.Debug
{
    public partial class Scratch_Debug : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack) 
            {
                StaticTest StaticTestInitialize = new StaticTest(); //execute static constructor
            }
            lblStaticTest.Text = StaticTest.s;
        }

        protected void btnSetS_Click(object sender, EventArgs e)
        {
            StaticTest.s = "Not Default";
            lblStaticTest.Text = StaticTest.s;
        }
        
    }
    public class StaticTest
    {
        public static string s
        {
            get
            {
                return _s;
            }
            set
            {
                _s = value;
            }
        }
        private static string _s;
        static StaticTest()
        {
            _s = "Default";
        }
    }

Open in new window

0
käµfm³d 👽Commented:
I am not able to reproduce your issue. Using the same code that you posted above, the IDE and page work as expected. You may try repairing your installation of VS2012. I don't know why you should have to do that, but that's the only thing I can think to offer at this time.
0
SamCashAuthor Commented:
käµfm³d 👽,

Thank you for your above Comment.  I got Friday through Monday off for "Veterans' Day" sorry I did not get right back to you.

No changes to the code previously submitted.

I get the same behavior after reinstalling vs2102.  So I decided to..
Test on two other boxes
Upload to a test server running Server 2008 and IIS 7
--Test from three different boxes both local and remote on the above Server 2008 and IIS 7
Got permission to have anonymous viewing set on that folder and send the url  to you http://vince.orodev.com/debug/scratch_debug.aspx. (READ BELOW  BEFORE CLICKING THE LINK BECAUSE YOU ONLY GET ONE CHANCE TO SEE.)

1.  If you go to this url it will initialize at "Default"
2.  Click the button to set the static object property to "Not Default"
3.  Do anything, like new tab, new window, new browser,  clear cache, reboot...

You will observe the label showing the static object property will NEVER return to "Default".
This confirms for me (same as stepping through the code with vs) that the object's constructor is not executed ever again (even with "new" ), so we always have "Not Default".  (note: in these tests on IIS 7 there is no vs2012 involved.)

The only way I found to get it back to "Default" to test again, is:
1.  upload my files again (no changes required.)
2.  recycle the application pool
3. restart IIS 7

I will upload my files to reset things to default, as soon as I submit this "Comment" so you can see  for yourself.  It will only show "Default" once and then be stuck at "Not Default".  Let me know and I will reset things if you need.

Thanks Again.
Sam
0
käµfm³d 👽Commented:
The only way I found to get it back to "Default" to test again, is:
That's exactly what I've been saying. The reason all of those work is because each of those restarts the application. Without doing any of those, you will have to wait for your application to be naturally recycled by IIS (
every 1740 minutes, by default). Only restarting the application will cause your default values to be re-initialized.

Recycling the app pool effectively restarts your application. If you want, you can fiddle with your app pool's recycle settings to make the timeout smaller. If you do this, and you wait the allotted time after visiting the page initially, then when you refresh the page after the app pool recycles (automatically), you should see the default value again.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
SamCashAuthor Commented:
käµfm³d 👽,

That is what I was expecting, everything is working correctly.

Thank you for the link.  I am sure this has been my issue (me not understanding how iis works).  I am still digesting the link...

I think I need to set "Idle Time-out (minutes)" shorter.   Is there an idle flag I can access?  Is the Idle Time-out "n" minutes from the last Request?

Thank you.

Regards
Sam
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.