I have some legacy code in C#, .Net 2.0 where someone dragged OpenFileDialog and SaveFileDialaog from the toolbox onto the form. This results in the open and save dialogs being instantiated when their parent dialog is created and remaining until the parent dialog is closed. The open/save forms are really only used in one place each for a support file that is not always opened/saved during the life of the parent dialog; this seems inefficient to me.
What I would do is:
using (OpenFileDialog openDlg = new OpenFileDialog() )
{
//initialize openDlg...
if (openDlg.ShowDialog() != DialogResult.OK)
{
//handle OK result
}
}
That way the OpenFileDialog will be disposed of when the using statement goes out of scope. Unless I am missing something the value of rapid disposal (and faster garbage collection) of a resource outweighs the small savings of not having to instantiate the Open/Save File dialogs when they are needed.
Even if the open/save dialogs were used every time their parent dialog is used, I don’t see any great value to having them around all the time. My question is am I missing something? Is there some greater efficiency to keeping the open/save dialogs around all the time?
I assume the answer will be the same for all the other standard dialogs: ColorDialog, FolderBrowserDialog and FontDialog.
Not necessary. These dialogs have a Dispose() method only because they inherit one from the Component class. They don't override the method since they don't actually have anything to dispose. All the system resources they use get released when the dialog closes. The Component.Dispose() implementation doesn't do any disposing either, it just makes sure that the component is removed from a IContainer collection.
This is otherwise an implementation detail of these dialog wrappers. Other components do normally have use for Dispose(), ToolTip being a good example. The auto-generated Dispose method for a form makes sure that this happens, check out the "components" field in the form's Designer.cs source code file. Which is why Component has a Dispose method that doesn't do anything important by default.
There's one teeny advantage to avoiding dropping the component on the form, it allows the .NET wrapper class for the dialog to be garbage collected. But the kilobyte or so that saves is a micro-optimization.
Take this at face value: if early disposing these class objects would have been important, Microsoft wouldn't have made them components.
I think the "on form" option is just supposed to be easier for a novice to implement, since the work is mostly in the editor instead of in code.
Good practice would be to do what your doing since you've stated that these dialogs don't need to sit around in memory very long, but if they were to be used many times, it's a good idea to leave it around and dispose of it properly when the application closes, simply depends on the situation.
Given the situation it sounds like your good going either way and I wouldn't lose much sleep over it, but regardless whether it does anything useful in it's dispose method, the way your using it is recommended, its just good practice.
The advantage is you can set up the dialog however you need (multiselect, initial directory, extensions) etc in the form designer.
Also the form designer makes it so easy to drag an OpenFileDialog onto your form that many developers just do it. Can't really blame them.
There's no significant advantage or disadvantage to either approach, I doubt you'll find any perceivable performance difference.
I generally create form-scope dialogs when I want to persist certain settings, such as filters, without having to set them each place I use the dialog. If a dialog is used only in one place, I use a using statement, as you have above.
I always wondered about this approach as well as I prefer the usage pattern in your snippet. The only possible reason I've ever been able to come up with is that by making them components, their properties can be configured in the designer.
Not a very compelling reason (IMHO).
I generally agree. But there could be a slight performance gain if the dialogs have a lot of 'default' property data. Think about a file open dialog with 50 file type filters.
Related
I have Windows Form that I use for a trading application, which, of necessity, has to display a large amount of information updating very rapidly (4 times per second).
The Windows Form I'm using has lots of controls (over 150 buttons and textboxes), and 6 datagridviews with multiple rows to display the information.
I have using different threads to perform the time-consuming operations (HTTPRequests, and various mathematical operations), but I am still finding that the GUI feels sluggish. I've noticed, in particular, that when I add more controls to the Form, things slow down, even though these extra controls are really 'doing' anything.
Can anyone explain why the mere presence of extra controls should make the GUI less responsive and/or recommend a completely different approach? Maybe I shouldn't be using Windows Forms?
Thanks.
It is hard to say something concrete without knowing your code.
A few generic ideas:
From your description, it sounds to me, like your application is very busy with repainting all the controls. Try experimenting with SuspendLayout() and ResumeLayout() and Invalidate() only those Controls that really need repainting.
Check if DoubleBuffering is enabled on both the Form(s) and ChildControls, it should be activated for most controls by default. But make sure you have it on.
Depending on your used .NET Frameworkversion check if you can use async/ await features for keeping the responiveness up.
See article MSDN Magazine article "Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads". This one is a few days old, but still absolutely valid.
Some events are fired more often than you expect or need. Check those events that cause repainting of controls (i.e. this will be where you add values to be displayed to the user) if these fire too often.
Your controls take a lot of memory and I wonder why you have so many, have you considered creating controls on the fly as and when needed. Double Buffering is a must but will not help if you are clogging up memory as it is for graphic display. You need to profile your program using performance counters to find out where the problem lies, are you disposing correctly for instance?
Also are you using too many threads? Are you using the thread pool, if not you should be!
Are your controls loaded with data?
I will think some more but profiling is what you need to do next.
I'm learning some C# and in the tutorials, they usually put most of the code on the button clicks for the sake of teaching. For example, if they were going to show a streamreader, they would do:
StreamReader sr = new StreamReader();
..inside the button's click function.
Is this a bad programming habit? From javascript, I remember reading a warning on some code I wrote that said something about creating a function inside a timeout event. Should all variables and objects be declared outside of the button click function?
I'm learning some C# and in the tutorials, they usually put most of the code on the button clicks for the sake of teaching
The reason that putting code inside a click handler would be bad is that a click handler is specifically related to the UI, and the rest of your code might not be.
A stream reader reads from a stream. Code that processes a stream should be grouped with it. Code that handles the fact that you clicked on the UI has nothing to do with reading from a stream, so it should be separated.
Generally you should group your code so that parts of your code that are logically similar are together, and that parts of your code that deal with entirely different things are separated. This will give you "high cohesion". It is related to the Single Responsibility Principle.
Should all variables and objects be declared outside of the button click function?
Absolutely not. If it makes sense to create a specific object when handling a UI event, do so.
However as I mentioned before, if you're dealing with non-UI things inside a UI click handler you're doing too many things at once. Split out your streaming code into another method, another set of methods, or into another object. This will make it easier to read your code, it will make your code have a better chance of being reusable, and it will make it easier to edit your code.
UI logic and flow is notorious for being kludgy and requiring a lot of work-arounds and special handling. It is also the area of your app that you will get the most feedback on, so it will undergo the most change. Everyone will have an opinion on how your UI should work, including non-technical users. If you guard yourself against this by separating your UI logic from the logic in the rest of your app, then those changes will be much easier to make.
You can create instances within your handlers, this is common practice as everything is taking place on the UI thread within your handlers. In addition once the method completes that variable will go out of scope and get marked for garbage collection.
It all depends on how long you need the object to live, if you wont use it outside the button event then it probably should be there so it gets garbage-collected when the event is finished, if you do need to use your objects outside then using a field in your class should be fine.
No it is not a bad idea to create instances in event handlers, but if there is any code that you may want to call multiple places in your code, it is best to that part of code to a separate method instead of trying to simulate button click events
Here is the scenerio:
On application open the user is asked to open a "Project"
Inside a project there are processes, categories, tasks, documents and notes.
There are a few more, but lets keep it simple. Most of the items above are lists that are bound to grids or treeviews.
Each of them have a separate database table and are linked with values in the database.
So after a user opens a project I could do something like this:
Get Processes that belong to Project 'A'
Get Categories that belong to each process
Get Tasks that belong to each category
Get Documents that belong to Project 'A'
Get Notes that belong to Project 'A'
and so on
The issue is then if the user closes this Project I have to clear every bound control and clear any variables related, then be ready to open another Project.
So what I am looking for is some advice for the way to handle this type of situation efficiently.
I am using C# .Net, and the application is a Windows Forms application.
Well, any way you slice it, the memory allocations done on load will have to be cleaned up at some point.
Depending on how you do your data access, you may have to do it manually, or .NET's garbage collector may take care of it for you (most likely).
For this type of application (given the limited requirements you've written), I would normally implement it as an MDI application so you could have multiple projects open at once. All of the project loading/disposing code would be run through the child window, so any time a child window is closed, the memory gets cleaned up automatically.
Even if you don't/can't do MDI, I would strongly recommend that you follow the dispose-on-unload model instead of keeping the same form open and reinitializing it with new data. The latter model is very prone to erroneous behaviour because of lingering data and/or state (which is programmer error, but is really difficult or even impossible to track down when trying to reproduce a client's issue). I've seen this pattern a lot in WinForms and it isn't pretty when the form controls and business logic start to get complicated. Dump the form and start again.
I've got a form in a 24/7 application that will probably be needed as many as 1000 time a day. Does it make sense to create/destroy this form every time I need it, or is this an example of a situation where the form should be permanent?
Does it make sense to create/destroy
this form every time I need it, or is
this an example of a situation where
the form should be permanent?
1000 times a day sounds like a lot. Creating and destroying does technically consume resources and takes time, but depending on what is on the form, it might not be that much. The question about whether or not you should destroy and recreate the form really lies in how the form works. If you don't re-create it, you have to worry about putting the form back in it's original state each time. By re-creating it, this is done for you. On the flip side, f it takes several seconds to pull the data to create the form, then keeping it might be the best option. Unfortunately, the best answer is, "It depends on each scenario."
Just keep it permanently. If that annoys the users then you can let it minimize to the status bar (making it disappear from the task bar) and allow users to show it again by either clicking on the status icon or the program itself (meaning that they can just tell the program to start and when it launches it checks if it's already running, sets the running instance to visible and closing the newly launched instance again).
Giving a good answer to this is hard due to the limited information you provide though.
I think this depends on if the use of the form is spread evenly during the day and if it holds any resources or handles of any kind.
But if it's a simple form that's easy to re-initialize I'd probably keep it open and just hide it when needed.
That really depends on how expensive it is to create the form and on whether or not it has any side effects. If the form can be created quickly (time required is well below the detection level of the user) then it is not unreasonable to create it every time.
If it is expensive to create and the users don't want to see it when it is not in use then you can just hide it when it isn't being used. However, be sure that it does not have any side effects. If it is still responding to events when it is hidden, then unexpected (usually bad) things can happen.
I was thinking of centralizing this functionality by having a single method that gets passed an AppState argument and it deals with changing the properties of all GUI elements based on this argument. Every time the app changes its state (ready, busy, downloading so partially busy, etc), this function is called with the appropriate state (or perhaps it's a bit field or something) and it does its magic.
If I scatter changing the state of GUI elements all over the place, then it becomes very easy to forget that when the app is in some state, this other widget over there needs to be disabled too, etc.
Any other ways to deal with this sort of thing?
Emrah,
Your idea is good. You need to limit the state structure and this is the only way to ensure reliable UI. On the other hand do not follow the "one function" idea to strictly. Rather continuously follow its direction, by creating a function and then do progressively refactoring all attributes to a single "setter" function. You need to remember about a few things on your way:
Use only one-way communication. Do not read the state from controls since this is the source of all evil. First limit the number of property reads and then the number of property writes.
You need to incorporate some caching methodology. Ensure that caching does not inject property reading into main code.
Leave dialog boxes alone, just ensure that all dialog box communication is done during opening and closing and not in between (as much as you can).
Implement wrappers on most commonly used controls to ensure strict communication framework. Do not create any global control framework.
Do not use this ideas unless your UI is really complex. In such case using regular WinForms or JavaScript events will lead you to much smaller code.
The less code the better. Do not refactor unless you loose lines.
Good luck!
Yes, this is the most time consuming part of the GUI work, to make a user friendly application. Disable this, enable that, hide this, show that. To make sure all controls has right states when inserting/updateing/deleteing/selecting/deselecting things.
I think thats where you tell a good programmer from a bad programmer. A bad programmer has an active "Save"-button when there is nothing changed to save, a good programmer enables the "save"-button only when there are things to save (just one example of many).
I like the idea of a UIControlstate-handler for this purpose.
Me.UIControlStates=UIControlstates.EditMode or something like that.
If having such object it could raise events when the state changes and there we put the code.
Sub UIControlStates_StateChanged(sender as object, e as UIControlStateArgs)
if e.Oldstate=UIControlStates.Edit and e.NewState=UIControlStates.Normal then
rem Edit was aborted, reset fields
ResetFields()
end if
select case e.NewState
case UIControlStates.Edit
Rem enalbe/disable/hide/show, whatever
Case UIControlStates.Normal
Rem enalbe/disable/hide/show, whatever
Case UIControlStates.Busy
Rem enalbe/disable/hide/show, whatever
Case Else
Rem enalbe/disable/hide/show, whatever
end select
end sub
#Stefan:
I think we are thinking along the same lines, i.e. a single piece of code that gets to modify all the widget states and everyone else has to call into it to make such changes. Except, I was picturing a direct method call while you are picturing raising/capturing events. Is there an advantage to using events vs just a simple method call?