I have a c# windows forms mp3 player application. I have the audio files in my Resources folder and a separate "MyAudio" static class which handles all the audio related work like playing and increasing volume etc.
From my Form, I just call the play method using:
MyAudio.Play(track);
In the MyAudio class, I have a WindowsMediaPlayer object declared as:
private static WindowsMediaPlayer obj=new WindowsMediaPlayer();
My Question is, in terms of efficiency and less memory usage, is it better to declare MyAudio class as static or non static? Is it wise to create a Object of the MyAudio class in form and then call the methods or directly call using class Name?
Also is it good practice to declare the instance variables as static?
Your question is indeed broad, but there are few design principles that you can take care of, while you are designing a class:
Do I need the object and it's state throughout the application lifetime
Do I need to maintain the state of class variables for future use
Do I need to multi-thread or parallelize the application at any point of time
Do I need to decouple the component in the future and used in other scenarios like Ajax based web scenario
Important thing in this case is that you are keen to maintain the state for the application lifetime and the amount of memory usage is fine for the application environment, since after initializing you would be able to get all the data from memory and don't need to query a source like database. However, this is good for the scenario where you need to initialize once and read as a static information in the rest of the application. In case you plan to re query the information, then the part purpose of using static type would be lost
Let's assume in the future you need to parallelize your code for performance enhancement, then static will come to haunt you, since it would be shared among threads and invariably would need a synchronization construct like lock, mutex, which will serialize all threads and thus purpose would be lost. Same things would happen in a Web / Ajax scenario and your static component cannot handle the multiple parallel requests and will get corrupted until and unless synchronized. Here instance variable per thread is a boon, as they do task / data parallelization without requiring a lock, mutex
In my understanding static is a convenience, which many programmers misuse, by avoiding the instance variable and using at will, without understanding the implications. From the GC perspective, it cannot collect the static variable, so the working set of the application would invariably increase till it stabilize and will not decrease until and unless explicitly released by program, which is not good for any application, until and unless we are storing data to avoid network database calls.
Ideal design would suggest to always use the instance class, which gets created, does its work and gets released, not linger around. In case there's information that needs to be passed from one function to another like in your case from Play to Pause to Stop, then that data can be persisted to a static variable and modified in a thread safe manner, which is a much better approach
If we just take example given by you since it's a windows form, which does operations like Play, then static would be fine, as it is an executable running on a system, but for testing imagine a scenario that you initiate multiple instances by double clicking and play around on each one, by pressing different operations, then they all will access same static object and you may get a corruption issue, in fact to resolve such scenario you may even chose your class to be singleton, where at a given moment no more than one instance can exist in the memory, like it happens for Yahoo messenger, no matter how many times you click, always same instance comes up.
There are no static instance variables. However its best practice to define static members if they don't have anything to do with a particular instance of the class.
Related
As per my knowledge, it is not advisable to use static variables in Web Applications. Now my question is, is it advisable to use static methods in web applications?is a static method use system memory as a static variable use?
please clarify my doubt.
Thanx in advance.
Yes, it is advisable to use static methods in a web application.
A static variable has very limited use in a web application, because all threads will share the same variable.
When it comes to methods, it's not a problem that all the threads access the same method, as the method itself won't change. The local data in a method is still separate for each call to the method, so several threads calling the same method at the same time is not a problem.
Generally speaking, if a method doesn't rely on any instance data, it should be static. I.e. if a method can be static (without any other chances to the method), it should be.
The reason you should avoid static variables is that they are often used to provide global state. This breaks encapsulation and makes maintaining and debugging programmes harder as any piece of code could change your variable.
In a threaded environment like ASP.NET this made worse by multiple threads potentially editing the same static variable's contents with non-deterministic results.
Static methods on the other hand can be a very good thing. They provide referential transparency which means the same inputs will always produce the same output and there's no side-effects changing state. This makes multi-threaded access much easier to reason about as threads cannot affect the processing of others by changing shared variables (assuming you're not using static variables of course).
It can also make unit testing easier and more robust as you don't need to test the underlying state of the world alongside your inputs and expected outputs.
It's advised to avoid static data because it introduces concurrency issues if the data is mutable.
Static methods that do not utilize mutable static data need not be avoided; sometimes they make sense for functionality that doesn't need to be specific to any specific instance.
I am currently working on performance tuning of an existing C# website. There is a class say.. MyUtil.cs. This class has been extensively used across all web pages. On some pages around 10/12 instances are created (MyUtil). I ran the "Redgate" performance profiler. The object creation is a costly operation according to RedGate.
Please note that each instance sets specific properties and performs specific operation. So I can not reuse the object as it is. I have to reset all the member variables.
I want to optimize this code. I have thought about following options. Kindly help me evaluate which is the better approach here :
(1) Create a "Reset" method in "MyUtil.cs" class which will reset all the member variables (there are 167 of those :(..) so that I can reuse one single object in an page class.
(2) Continue with the multiple object creation (I do have Dispose() method in "MyUtil")
(3) I thought of "object pooling" but again I will have to reset the members. I think its better to pool objects at page level and release them instead of keeping them live at the project level.
Any reply on this will be appreciated. Thanks in advance..!
Every app has multiple opportunities for speedup of different sizes, like kinds of food on your plate.
Creating and initializing objects can typically be one of these, and can typically be a large one.
Whenever I see that object creation/initialization is taking a large fraction of time, I recycle used objects.
It's a basic technique, and it can make a big difference.
But I only do it if I know that it will save a healthy fraction of time.
Don't just do it on general principles.
I would recommend that you always create new objects instead of resetting the objects. This is so for the following reasons
GC is smart enough to classify objects and assign them a generation. It depends on the usage of objects in your code. Profiling is done based on the execution pattern of code as well as architecture of code
You will be able to get optimum result from hardware if you use the GC and let it manage the process as it also decides the garbage collection thresh hold based on hardware configuration available and available system resources.
Apart from that, your code will be much easier and manageable. - (Though it is not a direct benefit, but should also give at least some weight to it.)
Creating object pool at page level is also not a good idea because to re-use the object, you will have to do two things, fetch it from pool and reset its properties, i.e. you will also have to manage the pool which is additional burden
Creating a single instance and re-using it with resetting properties might also not be a good idea cause when you need more then one instance of object, it will not work.
so the conclusion is, you should keep creating objects in the page and let the Garbage collector do its job.
I have class instantiated in a web service that, in a static member, holds on to some resources. If I was not statically holding on to these resources, I'd probably access them through some IDisposable object where I could release the resources on Dispose. Regardless of whether or not holding on to this session is a good idea, does .NET provide any way to call any clean up code when a type is statically deconstructed?
PLEASE DO NOT ANSWER THIS QUESTION WITH ANYTHING LIKE "STOP HOLDING RESOURCES IN A STATIC MEMBER VARIABLE". I understand the drawbacks to holding on to this information statically and am willing to accept the consequences (we're using it to cut processing time from 58 hours to 4 hours for some batch processing that we do). The question specifically is: given this situation, is there anyway for me to nicely clean up those resources?
EDIT:
I understand that the class will live for the rest of the process, but with static constructors .NET gives you the opportunity to do something when that type is loaded into memory. Can you do anything on the opposite end?
There actually is no way to do it from managed code. What you want is to handle your assembly being unloaded, but that doesn't happen under most circumstances when you want it to.
In more detail:
There is an AppDomain.DomainUnload event ( http://msdn.microsoft.com/en-us/library/system.appdomain.domainunload.aspx ) you can handle. This handles when your application domain gets unloaded from its hosting process (say ASP.NET).
However, if you are an EXE, or the hosting EXE is being recycled, this will not be raised. If you set up correctly, you might be able to handle the native DLL_PROCESS_DETACH and bounce that back to managed code, but because of the loader lock you will have to be very careful what you do from that context (anything that triggers an assembly load will deadlock).
You can read this for some insight on what cleanup is requited (hint: not much): http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx
Basically, the only thing you need to worry about is flushing buffers to disk, and if you need to do anything more complex, you have already screwed up. malloc(), and therefore new() could crash your program instantly. This applies to managed code as well.
The question does not really make sense, static lives for the lifetime of the process, when a process ends then everything is cleaned up by the OS. A process cannot continue to use resources if it is not running any longer.
When is the last point this static state is going to be important? At this moment, you should destruct it.
Destruct might mean something like "release some unmanaged memory, write out a cache to the database and set the static variable to null".
The last point of access will mean different things in different applications. In an ASP.NET application, you cannot reliably determine this point. It comes when the Application_End event or the AppDomain.Unload events fire, whichever comes first. The same in WCF. In a WinForms app you would to it after the main form has closed or as the last line of the main application.
In any case you need to do the cleanup yourself.
Alternative: You can encapsulate your state into a finalizable object. It will be cleaned up on AppDomain unload. If you write a so called critical finalizer you are pretty much guaranteed that your cleanup will execute.
You cannot destruct something that hasn't been instantiated.
I think you should use Singleton pattern instead of holding all data statically.
If the objects you are storing as static members properly implement IDisposable, then the .net runtime should take care of any resources when the app unloads. If any of the objects do not do this, then I suggest you create wrapper classes that implement IDisposable so that you can clean up after yourself.
IDisposable on MSDN
John's console application calls my DLL function many times (~15x per sec). I am thinking to put this function as a static method.
I know that :
It can only access static props and objects.
It doesn't need an instance to run the function.
But I don't know if these are the only questions which i need to ask myself.
Each John's calls to my function is in a new thread that he creates.
If there is an error in my function, how will this affect all other calls?
Should I make this function a regular function with instance to the class (which John will create)?
What about GC?
What is the best practice answer for this question?
Sounds like there could be a problem. Calling a method which operates on static (shared) objects in a multithread environment should ring some alert bells for you.
Review your code and if there's a chance that a shared object is accessed from two (or more) threads at the same time, make the object an instance field and make your methods instance methods.
Of course, whether or not there is a risk depends much on the actual code (which you don't show) but making all calls nonstatic means that you lower the potential risk.
Generally, if your static method doesn't use any state (i.e. both reading and writing to static fields and properties, or calling other static methods that do so), there won't be any side effects for the caller, no matter how many threads they start.
If you're asking for best practice, static methods are mostly a bad idea though. If at all, static methods should be only used for very generic utility functionality.
It's not recommended because you can't predict if requirements change and you need some state one day. Then you'd better use a class that the caller can instantiate, and you'll break all existing code that uses your function.
About garbage collection, yes sure that has some overhead, but that is currently the sacrifice if you go the route of memory-managed OO. If you want more control, use unsafe code or a language like C++ or Vala.
I would agree with Wiktor (+1), but would also add that if synchronization is required in the static method, it may be more efficient to use multiple instances. Otherwise, having many threads might be pointless as only one can access a critical section at a time.
I have a read only list that is shared across all instances of the application and won't change very often. Is it good practice to make a property on a static class to access this list? the list is filled from the database in the static constructor. Setting the app pool to recycle every night would guarantee the list would be up to date every day correct? Are there any reasons this is a bad idea? Thanks!
Nothing wrong with a static class. You could also use the cache, which would work in a similar way. The cache gives you the added bonus of being able to invalidate the cache on a timed basis of your choosing.
This looks like a good solution. You may want to use a sealed class instead, to avoid sub-classes messing with it.
The issue with global state is when it is being changed by the application. In this case, that's not a problem.
You should understand how static properties are stored.
Roughly, all static state is placed in the instance of RuntimeType (which, in turn, is created when static ctor is called). CLR via C# describes this mechanism in details.
In the light of that, this collection will be shared across all instances, but you should keep in mind all potential memory leaks (just imagine the situation when you're subscribing on the collection events and all pages became reachable even when they're closed etc.)
The second disadvantage of this approach is that this collection is not up-to-date.
The third disadvantage is that you need to take care about thread safety of this collection, which, in turn, will harm your performance.