in a .net web app is there something special about .aspx pages and the c# code behind pages that changes the behaviour of static variables.
i have a large number of application pages that were developed elsewhere and there is a common pattern running thru them where what i think should be an instance variable is declared as a static variable.
a more detailed statement of the question would be: if i have two web sessions a and b running on the same iis server in the same application pool, if a accesses the page in question and sets static variable x to value1 and then b accesses the same page and sets static variable x to value 2, my understanding is that value1 has been replaced by value 2. my dilemma is that this pattern is used repeatedly in the code, at a high level the code appears to work. the conclusion is that it is either luck (timing as in session a has abandoned the need for the variable before session b hits it) or there is something else going on.
i am open to suggestions whether this is a c# nuance or a developer bug.
Static properties/fields are fine in web applications as long as they are used for shared data which can acceptably disappear at any time, such as when an app pool recycles.
That said, their values are indeed shared inside an ASP.Net application unless they have a segregated backing mechanism, like Session.
Example
public static int UserId = 10; // BAD! everyone gets/sets this field's value
// BAD! everyone gets/sets this property's implicit backing value
public static int UserId {
get;
set;
}
// This case is fine; just a shortcut to avoid instantiating an object.
// The backing value is segregated by other means, in this case, Session.
public static int UserId{
get{
return (int)HttpContext.Current.Session["UserId"];
}
}
// While I would question doing work inside a property getter, the fact that
// it is static won't cause an issue; every call retrieves data from a
// database, not from a single memory location.
public static int UserId{
get{
// return some value from database
}
}
You may not see an issue until traffic is significant. Suppose a page retrieves a value, puts it in a static variable, uses it once, then completes execution. If the page executes quickly, there is only a very small (but dangerous!) window of overlap that you may not see unless the timing is right and/or traffic is high enough.
This can lead to hard-to-diagnose bugs, because they are dependent on timing and you probably will not see them when testing by yourself on your local machine.
Related
I have a static class with properties to store user's inputs:
public static class UserData
{
public static double UserInput1 { get; set; }
}
And I have nested methods that need the user's inputs
public static double Foo()
{
[...]
var input1 = UserData.UserInput1;
var bar = Bar();
[...]
}
private static double Bar()
{
var input1 = UserData.UserInput1;
[...]
}
The positive thing is that I do not have to pass all user inputs to Foo(), then to Bar() (and to further nested methods within Bar()).
The negative thing is that I have to get UserData.UserInput1 and other user inputs very often. I could change the code to get the user inputs only once:
public static double Foo()
{
[...]
var input1 = UserData.UserInput1;
var bar = Bar(input1);
[...]
}
private static double Bar(double input1)
{
[...]
}
Which one is faster?
The second one is the faster than the first one. Because you avoid to obtain the static property from UserData.
It's not a big goal works with static when we talk about performance cost due to the need to perform a lookup in the symbol table and track shared memory. By passing input values as parameters, this is avoided and slightly better performance is achieved.
But both options are ok. It's more important to focus on code readability and maintainability rather than performance unless you are working on a critical performance issue.
Which one is faster?
Using static mutable state in this way will be way slower in the long run. Because you will spend a bunch of time trying to find and fix bugs. This time could be better spent doing things that will actually help performance, like profiling and optimizing code.
Try to make method that compute anything take the required input as parameters. Try to make input fields properties of the associated UI class. This should help keep the code simple and understandable.
Accessing a static property will be translated to a indirect memory access. Passing a parameter to a method might be free if the parameter is already in a register, or might involve a bit more work if it needs to be loaded, moved or passed on the stack. But we are talking about single digit cycles here, optimization on this level should only be done in super tight loops that are run many millions of times each second, and then you should typically ensure that all methods can be inlined, side stepping the problem.
If you're worried about such micro-optimizations (which you generally wouldn't need), consider using inlining.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.methodimploptions?view=net-7.0
PS: using one over the other, or using AggressiveInlining, will not save you anywhere close to the 1ms you are hoping for, under non-extreme/farfetched scenarios.
It was suggested to me to use a singleton in my application and I am wondering if this is the correct approach.
I have a windows gaming handled tool app I am developing. It consists of two windows. A main window and a quick access menu window. These windows share similar components, like on both windows I have sliders to adjust screen brightness, volume, cpu TDP, etc. Both windows should show the same values.
Currently I am using a static class on a separate thread to get these values. It loops through and gets these values every few seconds via dispatcher timer. It is important to note that values like TDP require an external program that reads CPU MSR or MMIO values, so two threads should not concurrently be calling these read routines, as it can cause the external program to crash. These values then get stored into a static class in the main window housing the "global" variables.
public static class GlobalVariables
{
//TDP global
public static double readPL1 = 0;
public static double readPL2 = 0;
public static double setPL1 = 0;
public static double setPL2 = 0;
//brightness and volume setting
public static int brightness = 0;
public static int volume = 0;
}
I always want this thread running as long as the application is running. I thought static would be appropriate since this isn't a scaled up app that would need dozens of this class running. I also might need to create events from this as well.
Would a singleton with an initialization in both windows serve the same function?
Would the stored variables stay consistent for both windows?
Would using static routines cause an issue in my program (something that isn't scaled up)?
One last question: if I go the singleton route and I want this code running separately from the UI should I initialize the class on a newly created thread in the window?
Thanks in advance!
Would a singleton with an initialization in both windows serve the same function?
A correctly implemented Singleton is initialized the first time it is accessed in an Application session and retains its value for the duration of the session.
Would the stored variables stay consistent for both windows?
Wherever you access it in the code (from different Windows and other types that can be from any assembly), you will always get the same value.
Would using static routines cause an issue in my program (something that isn't scaled up)?
Too vague question. The answer is from the details of the task, the chosen method of implementation.
Potentially, static implementations (including Singleton) have security issues, as static members have global access and can be intentionally malformed.
Therefore, only constants and methods are usually made static.
But such security in WPF is actually quite ephemeral.
With the "standard" implementation, it is still possible to get any Window, any of its elements from the Resources, Visual and Logical Trees.
In terms of scalability, there could be some issues if you need to add multiple View instances in the future. Then each of them may require its own instance with data, and not a static one with the same data for all.
One last question: if I go the singleton route and I want this code running separately from the UI should I initialize the class on a newly created thread in the window?
If there are no thread-dependent elements in the code (it usually only UI elements), then the initialization flow usually does not matter.
If the initialization is long, then in order not to lag the GUI, it is better to do it asynchronously.
I am tasked with writing a system to process result files created by a different process(which I have no control over) and and trying to modify my code to make use of Parallel.Foreach. The code works fine when just calling a foreach but I have some concerns about thread safety when using the parallel version. The base question I need answered here is "Is the way I am doing this going to guarantee thread safety?" or is this going to cause everything to go sideways on me.
I have tried to make sure all calls are to instances and have removed every static anything except the initial static void Main. It is my current understanding that this will do alot towards assuring thread safety.
I have basically the following, edited for brevity
static void Main(string[] args)
{
MyProcess process = new MyProcess();
process.DoThings();
}
And then in the actual process to do stuff I have
public class MyProcess
{
public void DoThings()
{
//Get some list of things
List<Thing> things = getThings();
Parallel.Foreach(things, item => {
//based on some criteria, take actions from MyActionClass
MyActionClass myAct = new MyActionClass(item);
string tempstring = myAct.DoOneThing();
if(somecondition)
{
MyAct.DoOtherThing();
}
...other similar calls to myAct below here
};
}
}
And over in the MyActionClass I have something like the following:
public class MyActionClass
{
private Thing _thing;
public MyActionClass(Thing item)
{
_thing = item;
}
public string DoOneThing()
{
return _thing.GetSubThings().FirstOrDefault();
}
public void DoOtherThing()
{
_thing.property1 = "Somenewvalue";
}
}
If I can explain this any better I'll try, but I think that's the basics of my needs
EDIT:
Something else I just noticed. If I change the value of a property of the item I'm working with while inside the Parallel.Foreach (in this case, a string value that gets written to a database inside the loop), will that have any affect on the rest of the loop iterations or just the one I'm on? Would it be better to create a new instance of Thing inside the loop to store the item i'm working with in this case?
There is no shared mutable state between actions in the Parallel.ForEach that I can see, so it should be thread-safe, because at most one thread can touch one object at a time.
But as it has been mentioned there is nothing shared that can be seen. It doesn't mean that in the actual code you use everything is as good as it seems here.
Or that nothing will be changed by you or your coworker that will make some state both shared and mutable (in the Thing, for example), and now you start getting difficult to reproduce crashes at best or just plain wrong behaviour at worst that can be left undetected for a long time.
So, perhaps you should try to go fully immutable near threading code?
Perhaps.
Immutability is good, but it is not a silver bullet, and it is not always easy to use and implement, or that every task can be reasonably expressed through immutable objects. And even that accidental "make shared and mutable" change may happen to it as well, though much less likely.
It should at least be considered as a possible option/alternative.
About the EDIT
If I change the value of a property of the item I'm working with while
inside the Parallel.Foreach (in this case, a string value that gets
written to a database inside the loop), will that have any affect on
the rest of the loop iterations or just the one I'm on?
If you change a property and that object is not used anywhere else, and it doesn't rely on some global mutable state (for example, sort of a public static Int32 ChangesCount that increments with each state change), then you should be safe.
a string value that gets written to a database inside the loop - depending on the used data access technology and how you use it, you may be in trouble, because most of them are not designed for multithreaded environment, like EF DbContext, for example. And obviously do not forget that dealing with concurrent access in database is not always easy, though that is a bit away from our original theme.
Would it be better to create a new instance of Thing inside the loop to store the item i'm working with in this case - if there is no risk of external concurrent changes, then it is just an unnecessary work. And if there is a chance of another threads(not Parallel.For) making changes to those objects that are being persisted, then you already have bigger problems than Parallel.For.
Objects should always have observable consistent state (unlike when half of properties set by one thread, and half by another, while you try to persist that who-knows-what), and if they are used by many threads, then they should be already thread-safe - there should be no way to put them into inconsistent state.
And if they want to be persisted by external code, such objects should probably provide:
Either SyncRoot property to synchronize property reading code.
Or some current state snapshot DTO that is created internally by some thread-safe method like ThingSnapshot Thing.GetCurrentData() { lock() {} }.
Or something more exotic.
I know what static class variables do in a C++ class, what I'm not very clear about is the life-cycle of static class variables in a C# class used for an ASP.NET web app. Here's a code example:
namespace MyWebApp
{
public static class MyFunctions
{
private static string _cachedID;
public static string getID(string strValue)
{
if(_cachedID == null)
_cachedID = strValue;
return _cachedID;
}
}
}
Can someone explain it in plain English for me?
I've read somewhere.
A static variable/field comes into existence before execution of the static constructor for its containing type, and ceases to exist when the associated application domain ceases to exists.
Since you are asking this question in the context of a multithreaded ASP.NET application, you should be extremely careful. Checkout the following scenario:
2 users Bob and Alice call the getID method at exactly the same time passing different arguments. Bob passes Foo and Alice passes Bar. Since this is the first call, the _cachedID variable is not yet initialized so both enter the if condition, Bob with a slight delay. So Alice sets the _cachedID static variable to Bar and a microsecond after, Bob sets it to Foo. Now the code continues and the function returns Foo for both users. Bob of course is happy because that's what he wanted, but Alice wanted Bar.
For example if you wanted to perform a one time initialization in a multithreaded environment you might consider using the thread safe version of the Singleton Pattern.
The moral of this is that you should be extremely careful when dealing with shared/static data in an ASP.NET application. If you need to use it you need to properly synchronize the access to it or very bad things could happen. And they usually happen in production when your application is concurrently accessed by multiple users. On your local PC everything will work fine.
And back to your original question about the lifetime of a static fields: it is tied to the lifetime of the application domain.
Classes which you can't and dont have to make an object of but you can only acces it from a static context.
you would use your example like this:
MyFunctions.getID("bla");
http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx
I would like to wrap Session variables in a manner similar to that discussed on CodeProject.
public static class WebSession
{
private const string CurrentUserKey = "CurrentUser";
private static HttpSessionState Session
{
get { return HttpContext.Current.Session; }
}
public static bool Exists
{
get { return Session != null; }
}
public static User CurrentUser
{
get { return Session[CurrentUserKey] as User; }
set { Session[CurrentUserKey] = value; }
}
}
Here is my question: if I have to access CurrentUser multiple times in the same page, would I get a performance improvement by assigning it to a local variable instead of accessing the wrapping property? Or does the HttpSessionState make sure the object is only deserialized once per request, so that subsequent calls in the same http request don't cost any more?
Thanks,
Aaron
There is an in-memory copy of your Session state on each request. Therefore the only cost that you would be saving by locally copying a session variable is that of the cast from Object to your type. The in-memory copy is then added to Session at the end of the request.
Whether or not Session is serialized and deserialized on a page depends on what Session Provider you choose. For In-proc Session State, no serialization occurs. For Session Servers the object must be serialized first.
There is an in-memory copy. You get negligible performance improvement from caching the value; it would save only a Dictionary lookup, which will be too fast to notice unless you're doing it a zillion times per page load.
Also important to note is that for a given key, each retrieval returns a reference to the same instance, and Session keeps a reference too. That means, if you retrieve an object from Session and modify it, you need not call the setter again to re-serialize it.
I just asked a question about this same thing:
Are .Net property setters ever called implicitly?
I did some work pulling apart session recently, and from what I could see, the entire state object is deserialized once and once only per request. Of course, it is easy enough to check - just fetch it out twice and check ReferenceEquals.
Of course, placing the value in a field between uses would save some "lookup" time, but you should only pay the deserialization cost once.
If you really wanted to be sure, you could also double-check this by implementing ISerializable and logging serialize / deserialize calls.
some good articles to read
http://msdn.microsoft.com/en-us/library/aa479041.aspx
http://msdn.microsoft.com/en-us/magazine/cc163730.aspx#S5