Will InstanceContextMode.PerCall in WCF instantiate all static variables/methods? - c#

In my WCF code, user's id and name are stored in static variables. It is retrieved from HttpContext.Current.User.Identity.Name and a database hit. Also there are other static variables to store connection string, log file related stuff etc.
Recently i found myself in a race condition where a second call from my client set the user name when the first call was still processing. This resulted in first call reading user data updated by the second call.
To avoid this, I read about InstanceContextMode.PerCall and how it makes static variables behave like non-static for every call.
My questions are
1) If i use InstanceContextMode.PerCall, does that mean it will instantiate all static variables and methods? I am planning to use this only to get new user data for every call. However, I assume this will also make a new instance for connection string static variable, log file and other static variables. Is this correct? Will it affect performance (reading again from web.config etc)?
2) Is there a way to use InstanceContextMode.PerCall but to create instance only for user data related static variables and leave the connection string related static variables?
3) Is a dispose method ( implementing IDispose) mandatory to dispose off the static variables once the call is done?

First of all not sure why you have all those data in a static variable? that looks like a bad design. When you say InstanceContextMode.PerCall; to my understanding every call have a separate copy of the data and it's unique per call.
If you want your data to be not modified then try declaring them as static readonly instead. Lastly, you should opt for a better design rather.

Related

Is using property getters for initialization (to avoid having to call methods in specific order) bad practice?

Suppose I have a class that provides some data to my application. Data initially comes from database, and I provide it through some methods that handle the whole database thing and present the result as a usable class instead of raw query result. This class has to do some setup (not complex) to make sure any method called can use the database (e.g. connect to database, make sure it contains some critical info, etc). So, were I to put it in a method (say, method Init(), that would handle checking for database, connecting to it, verifying that it does contain the info), I would have to make sure that this method is called before any other method.
So, I usually find that instead of doing this:
public class DataProvider
{
private SqlController controller;
public void Init()
{
controller = new SqlController();
controller.Init();
controller.ConnectToDataBase();
CheckForCriticalInfoInDatabase();
}
public Data GetData()
{
// get data from database (not actually going to use raw queries like that, just an example)
var queryResult = sqlController.RunQuery("SELECT something FROM SOME_TABLE");
// and present it as usable class
Data usefulData = QueryResultToUsefulData(queryResult);
return usefulData;
}
...
}
and then always making sure I call Init() before GetData(), i do something like
private SqlController _controller;
private SqlController controller
{
get
{
if (_controller == null)
{
_controller = new SqlController();
_controller.Init();
_controller.ConnectToDataBase();
CheckForCriticalInfoInDatabase();
}
return controller;
}
}
So, now i can be sure that i won't use an uninitialised SqlController, and I don't have to do that same null check in every method that uses it. However, I never noticed getters being used this way in other peoples' code.
Is there some pitfall I don't see? To me it looks like it's the same as lazy initialization, with the exception being that I use it not because the initialization is heavy or long, but because I don't want to check the order in which I call methods. This question points out that it's not thread-safe (not a concern in my case, plus I imagine it could be made thread-safe with some locks) and that setting the property to null will result in unintuitive behaviour (not a concern, because I don't have a setter at all and the backing field shouldn't be touched either way).
Also, if this kind of code IS bas practice, what is the proper way to ensure that my methods don't rely on order in which they are called?
As #madreflection said in the OP comments, use a method for anything that is possibly going to be slow. Getters and setters should just be quick ways of getting and setting a value.
Connections to dbs can be slow or fail to connect so you may have catches setup to try different connection methods etc.
You could also have the checking occur in the constructor of the object, that way the object cannot be used without init() being run in a different function, saving on time tracing where an error is actually occurring.
For example if you had one function create the object, do a bunch of 'stuff' then try to use the object without running init(), then you get the error after all of the 'stuff' not where you created the object. This could lead you to think there is something wrong in whatever way you are using the object, not that it has not been initialised.

Local variable vs private field effeciency

Is there like a rule of thumb about when to go either over the other?
Im curious because i have a dilemma here, where i have a very frequently used method, return a custom class type that is rather large. Im wondering if it wouldnt be cheaper to hold an instance of this custom class in a field, and then in the method just change and return it every time, rather than creating a whole new object as would be the case if i had a new class instance created in the method every time.
The main difference between returning a newly created instance of a class and returning a field is enormous: in the latter case, the instance is shared because all clients receive a pointer to the same instance. That means: whenever any of the clients (or the original creator of the instance) changes something in the instance, all clients will now see all those changes. In the former case, all instances are different, and changes affect only the current client.
So take a really close look at the requirements and find out which of the behaviors is required. Getting them wrong can have devastating effects.
What you seem to ask for is a so called lazy field. You declare it as System.Lazy<> like so
private System.Lazy<YourClass> mYourClassInstance;
...
mYourClassInstance = new System.Lazy<YourClass>(() => new YourClass());
and then you can get the instance via
mYourClassInstance.Value
anywhere you want but the value (instance) is only created once.

Read data once and use later

I read values in from a file on startup of my application.
I'd like to use those values during a condition in a timer every xx seconds later in my program's execution.
I don't want to read the file again. How do I go about referencing the values initially read in?
The timer is in a completely different project/class to initial reading of the file.
Assign them somewhere!
If you're reading from the file and creating the timer condition in the same place, you could even use a local variable to store the values.
If they need to be accessed later but you don't want to recreate them, you could store them in a field in the class where this is happening.
If these values will be used elsewhere in your application, but will remain relevant as long as this class' type is around, you could store them in a static field or property.
If you want them to be loaded on-demand and then saved for subsequent access, you could use a Lazy<T> type to store them.
If you are needing to reference them from another class and hold them in memory - create a public static property somewhere to which you can assign the data.
public static MyDataType Data{ get;set;}
... where MyDataType is an object that holds your data. You can then test for Null in your timer method to make sure this has happened before continuing.

What are static C# class variables for in ASP.NET?

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

Static methods in a class - okay in this situation?

Hey all - I have an app where I'm authenticating the user. They pass username and password. I pass the username and password to a class that has a static method. For example it'm calling a method with the signature below:
public class Security
{
public static bool Security.Member_Authenticate (string username, string password)
{ //do stuff}
}
If I have 1000 people hitting this at once, will I have any problems with the returns of the method bleeding into others? I mean, since the methods are static, will there be issues with the a person getting authenticated when in fact they shouldn't be but the person before them was successfully authenticated ASP.Net returns a mismatched result due to the method being static? I've read of issues with static properties vs viewstate but am a bit confused on static methods. If this is a bad way of doing this,what's the prefered way?
This will not happen. When a method is Static (or Shared in VB.NET), then you're safe as long as the method doesn't rely on anything other than the inputs to figure something out. As long as you're not modifying any public variables or objects from anywhere else, you're fine.
A static method is just fine as long as it is not using any of persistent data between successive calls. I am guessing that your method simply runs a query on the database and returns true/false based on that.
In this scenario, I think the static method should work without a problem, regardless of how many calls you make to it.
ASP.net does use all sorts of under-the-hood thread pooling, which can make static methods and fields dicey.
However, you can avoid most threading issues with a static method by using only locally-scoped variables in that method. That way, each thread (user) will have their own in-memory copy of all the variables being used.
If you use higher-scoped variables, make sure to make all access to them thread-conscious.
Throwing exceptions is not a good practice as it makes the .net runtime to create extra infrastructure for catching them. To verify this create a class and and populate it with some random values using a loop. Make the loop iterate for a large counter like 10,000. Record the time it takes to create the list. Now enclose the instance creation in a try..catch block and record the time. Now, you can see the exceptionally large difference.
e.g
for(int i=0; i<10000; i++){
Employee emp = new Employee();
emp.Name = "Random Name" + i.ToString();
}
Versus
for(int i=0; i<10000; i++){
try{
Employee emp = new Employee();
emp.Name = "Random Name" + i.ToString();
}catch{}
}
Although there is no fixed solution whether to throw exception or not, it is a best practice to create alternate flows in your program and handle every condition with proper return values. Exceptions should be thrown only when the situation can be justified as exceptional.
While I can see the value of the static method in regards to the perceived performance gains, I believe the real issue here is whether the gains (and risks) are worth the maintenance kludge and security weakness you are potentially creating. I believe that most people would warn you away from providing a public method that accepts an user credentials and returns success or failure. It potentially provides an easy a method for hacking.
So, my point is philosophical. Otherwise, I agree with others who have pointed out that restricting the code to use local variables should ensure that you do not have any problems with side effects due to concurrent access of the method, even on different threads, i.e., if you invoke the method on a ThreadPool thread.
Maybe it's better to use public static void Authenticate(string, string) which throws an exception if something goes wrong (return false in original method) ?
This is a good .NET style. Boolean function return-type is the C style and is obsolete.
Why don't you have the user class with username and password and a method that is called authenticate?

Categories