I created a class awhile back. I used List.Add(this) inside of the class so I could access the controls I created later. It seemed to be very useful and I do not know how to create controls (more than one in the same parent control without a predefined limit) and access them later.
I was looking for Add(this) on the internet and couldn't find anymore information on it.
Is this a large resource hog or ineffective? Why can't I find more information on it? It seems very useful.
public class GlobalData
{
private static List<Member> _Members;
public partial class ChildrenPanel
{
private static List<ChildrenPanel> _ListCP = new List<ChildrenPanel>();
//X and Y position Panel | Container is the control recieving the Control
public void CreatePanel(int X, int Y, Panel Container)
{
//
// pnlStudent
//
_pnlStudent.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
_pnlStudent.Controls.Add(_lblCLastName);
_pnlStudent.Controls.Add(_lblCFirstName);
_pnlStudent.Controls.Add(_lblGrade);
_pnlStudent.Controls.Add(_lblSelected);
_pnlStudent.Controls.Add(_lblSeason);
_pnlStudent.Controls.Add(_lblAvailable);
_pnlStudent.Controls.Add(_lblGender);
_pnlStudent.Controls.Add(_ddlGrade);
_pnlStudent.Controls.Add(_ddlSelectedSports);
_pnlStudent.Controls.Add(_ddlAvailableSports);
_pnlStudent.Controls.Add(_ddlSeason);
_pnlStudent.Controls.Add(_rdbFemale);
_pnlStudent.Controls.Add(_rdbMale);
_pnlStudent.Controls.Add(_btnRemoveChild);
_pnlStudent.Controls.Add(_btnRemoveSport);
_pnlStudent.Controls.Add(_btnAddSport);
_pnlStudent.Controls.Add(_txtCLastName);
_pnlStudent.Controls.Add(_txtCFirstName);
_pnlStudent.Location = new System.Drawing.Point(X, Y);
_pnlStudent.Name = "pnlStudent";
_pnlStudent.Size = new System.Drawing.Size(494, 105);
//Still playing with the tab index
_pnlStudent.TabIndex = 10;
// Adds controls to selected forms panel
Container.Controls.Add(_pnlStudent);
// Creates a list of created panels inside the class
ListCP.Add(this);
}
Just make sure that you Remove the instance again when it's no longer needed, otherwise the List holding a reference to it will keep it in memory forever (Welcome to memory leaks in .NET after all).
I may revise this answer once I see some code, but my initial response is that it is not a resource hog. As to whether it is effective or not, some example code will be required.
Adding an object to a collection does not take up a large amount of resources because you are simply adding a reference to the object into the collection. You still only have a single object, but two (or more) variables that point to that object, so the only extra resources you are using are the minimal memory used by the references.
If your List is static or otherwise globally available, then you're doing something very bad.
ASP.Net is structured such that every request to your page - including postbacks - from every user results in a new instance of the page class. that's a lot of page instances. If references to all these instances are saved somewhere, the instances can never be garbage collected. You've created something analogous to a memory leak and you'll quickly find yourself running out of resources after you deploy to production.
The really dangerous thing here is that if you only do functional testing and no load testing the problem will likely not show up during your tests at all, because it will work fine for a few hundred (maybe even thousand) requests before blowing up on you.
If you're worried about dynamic controls, there are several better ways to handle this:
Put a fixed limit on the maximum number of controls you will allow, and add all of them to the page up front. Then only show/render them (toggled via the .Visible property) as you need them.
Make it data-driven. Rather than dynamically add a control, insert something to a database table and then bind a query on that table to a repeater or other data control (my preferred method).
Just make sure you're recreating every dynamic control you need at the right place (Pre-Init) in the page lifecycle.
Related
I have the following problem: An array of chart Series is passed from one form to another to be visualized in the child form i do this in order to enlarge the viewing area of a chart i have in my main window. It all works fine until i close the second form to which my Series have been passed at this point my application crushes an a null object reference is raised. Now I suspect my Series have been garbage collected upon that form termination. Any Ideas how this can be fixed and safely close that form without destroying the data?
Here is the code leading to the creation of the form.
Series[] tpSeries = { chart2.Series["S1"], chart2.Series["S2"] };
Dictionary<string, NumericUpDown> netParams = new Dictionary<string, NumericUpDown>()
{
{"N", numVertecies},
{"S", numS},
{"R", numR},
{"Gamma", numGama},
{"Beta", numBeta},
{"G", numG},
{"C0", numCzero},
};
TimePlotAnalysis tpForm = new TimePlotAnalysis(tpSeries, netParams); // N, s, r, gamma, beta, g, c_0
tpForm.Show();
Basically, your data should be in a separate class, then you simply share a class instance between forms.
There are many different ways to do this, depending on your particular use case. Here are a few examples:
How to share data between forms?
To Pass Values between two forms using C#
http://colinmackay.scot/2005/04/22/passing-values-between-forms-in-net/
Depending on your specific requirements, you might want to implement this object as a "singleton":
http://csharpindepth.com/Articles/General/Singleton.aspx
Now I suspect my Series have been garbage collected upon that form termination.
The issue has nothing in common with GC. You pass array of Series objects taken from a chart control in one form to another form, where (although you didn't show) I suspect you add them to another chart control.
Let take a look at Series class documentation.
Inheritance Hierarchy
System.Object
System.Windows.Forms.DataVisualization.Charting.ChartElement
System.Windows.Forms.DataVisualization.Charting.ChartNamedElement
System.Windows.Forms.DataVisualization.Charting.DataPointCustomProperties
System.Windows.Forms.DataVisualization.Charting.Series
Following the hierarchy, here is the base class definition
public abstract class ChartElement : IDisposable
Note the IDisposable? Now I guess you understand what is happening. When you close the second form, the Dispose method is called on the form and all the controls. The correct dispose implementations will in turn call dispose on any disposable object they hold (and we can assume MS controls do correctly implement the disposable pattern).
Shortly, I think the Series objects passed to the second form are disposed.
To fix the problem, as Reza Aghaei correctly pointed out in his comment, you should not pass Series objects to the second form, but the data that allows them to be recreated there. Or at least make sure you really create a new Series objects from the ones you pass.
The viewstate of a c# asp.net app that I am working on stores a ton of stuff via ViewState["SomeKey"] not to mention behind the scene stuff for several grids etc... and it is bloated.
I'm tasked with getting the viewstate size down...
I have found that within the app, viewstate is used to store various objects used throughout the code and I would like to use something more appropriate that stays session side (like session["SomeKey"]) or simply repopulate the objects again serverside... anyway...
I'd like to find where the largest benefit can be achieved by finding the heaviest objects that are stored in viewstate throughout the code... That is assuming they are serialized which I guess they must be... rather than holding a reference and hoping the object is in memory when posted back???
I would like to do something like the following...
var vsSomeKey = ViewState["SomeObjectKey"];
vsSomeKey.length.....
... with the hope of finding how much space is being used in viewstate for this key at this point in time... Any ideas?
I have a list view in the Panorama item, i would like to redirect to a new page to display more details about the item i have selected. May i know how do i do about this?
My current idea is to , When clicked , it will store the variable into the class file and my the other form when loaded it will always extract from that class file variable and search from the list.
I'm planning to keep a list of array, do i keep it in the class file so that it is accessible to all? If so , how do i do that too?
It looks like you could use up a lot of memory for transient data. Have you considered just calling Navigate() to load your new page and passing the instantiating data as post data - like here. This way you only create the new page with the data needed and don't hog memory.
I would personally use a RingBuffer for this... http://en.wikipedia.org/wiki/Circular_buffer
And I would have the indexer return the Image associated with the index. I would additionally have the TotalFrames present and returned via the Length of the List entries or similar. (Even if past the bounds of the list by using modulo)
I would also have a float indexer which would operate on values such as 25.7 or a string operator which took Degrees form.
I would also overload the operators to allow for rotation based on these methods accordingly. (For sliding and gestures inter alia)
You would then have a single enumerator with two operating styles, a repeating and a non repeating for going through the frames (including in reverse)
And this was just off the top... don't make me do an example :p
Imagine that I have a several Viewer component that are used for displaying text and they have few modes that user can switch (different font presets for viewing text/binary/hex).
What would be the best approach for managing shared objects - for example fonts, find dialog, etc? I figured that static class with lazily initialized objects would be OK, but this might be the wrong idea.
static class ViewerStatic
{
private static Font monospaceFont;
public static Font MonospaceFont
{
get
{
if (monospaceFont == null)
//TODO read font settings from configuration
monospaceFont = new Font(FontFamily.GenericMonospace, 9, FontStyle.Bold);
return monospaceFont;
}
}
private static Font sansFont;
public static Font SansFont
{
get
{
if (sansFont == null)
//TODO read font settings from configuration
sansFont = new Font(FontFamily.GenericSansSerif, 9, FontStyle.Bold);
return sansFont;
}
}
}
For items you wish to create once and then re-use there are two relevant patterns: Singleton and Cache. If you will re-use the item forever, the Singleton is OK. The memory allocated to that instance will never be cleared. If you will re-use the item for a while, but then maybe that function won't be used for a few days, I suggest using the cache. Then the memory can be cleared when the item is no longer in use.
If you are using the Singleton, you probably want to just init the Fonts directly rather than using the Lazy init pattern. To me, Fonts sound pretty simple and not likely to error out. However, if the item might fail during construction (perhaps due to a missing font file or something), then lazy pattern at least allows it to retry next time. You cannot redo a static initializer later, even if it fails, without restarting the whole application. Be careful to limit those retries!
Finally, the name of your class "ViewerStatic" raises a concern. There is an anti-pattern known as the "God" object. I call it the "bucket". If you create it, stuff will come. You will soon find all kinds of stuff being dumped in the bucket. Your ViewerStatic class will become huge. It would be better to have a class called "FontFlyWeights" and then another one called "ConstantStrings" or "SystemDialogFactory" ... etc.
That seems fine to me, but is it really necessary? The simple approach would be to just create new fonts and dialogs when you need them, then Dispose them if necessary and let the garbage collector clean them up.
Have you measured to see if the simple approach has a noticeable cost that makes it worth adding the complexity of caching shared objects?
Please note this is done in WPF/C# and not in .net2.0 Winforms
I have a ListBox which contains objects of say Class X. Class X contains a BitmapSource object which is displayed in the listbox, so it displays similar to [Image] [Text]
This is loaded via the use of the CreateBitmapSourceFromHBitmap - note also that I call DeleteHBitmap to delete the handle of the HBitmap during this call, which is well known to do from posts I've seen on google/etc
I have a tree which contains said ListBox in each TreeViewItem - typically the tree has several items loaded. Users can drag/drop these images into different TreeViewItems. To handle these operation I manually call the operations:
<code>
ItemCollection.RemoveAt
</code>
<code>
ItemCollection.Insert
</code>
to move the images from the ListBox item collection, note when I insert I create a new Class X object to insert into the ListBox item collection
I have noticed I get a consistent memory leak from calling such operations several times, over the space of 5-10 mins of consistent dragging and dropping.
My question is:
Am I handling the moving of the BitmapSource's correctly? Is there something I'm doing to cause the Images to not be fully removed from the ItemCollection?
Or is there something fundamental I've missed?
Which is the definition of the variable that holds the image in you ClassX??? The problem may be in the fact that you are creating a new ClassX and the old one is no being deleted by the GC making the head have two different instance of ClassX.
Since you are using unmanged code (CreateBitmapSourceFromHBitmap) you should check if all the finalize method are correctly called (though close or dispose probably) and that the are no static references that can be pointing to your ClassX.
Remember that if you ClassX is not removed the Bitmap instance will be reachable in the graph made by the GC making it not to remove it from the heap.
I recommned using perfmon and add the .Net memory object to see if there are any object that survived finalize or pinned object, those are the one you are probably interested regarding the memory leak.
I hope it helps :P, but it will be nicer if you put the code of the ClassX.