i have a c# application and there are a lot of forms with controls.
And every time when i run my application, forms which have many controls open slow.
So is there any way to make it open faster?
As you can see from the comments, there isn't one universal "make things faster" technique. You need to find the bottleneck and fix it. Here are some pointers:
Are all your controls on all your forms added statically in the designer, or added dynamically at runtime based on environment/user details/loaded dynamically via reflection? These can significantly slow down UI load time.
Do you have hundreds of controls on a single form? If so, consider splitting your forms to smaller chunks.
Do you have complex logic or data access during your Form_Load events? This can also slow down UI responsiveness. Consider starting the application "clean", and then loading the data asynchronously.
Use a profiler! Find a good, simple profiler to see where, exactly, you're spending your time. You'll often be surprised at what actually takes time. Use a trial version of a good, established profiler like dotTrace or Ants, and consider buying it for the future.
Instead of making it load faster, I would recommend you to give better user experience to your user.
First, load a Splash View (with loading progress) first. On next thread running in background, load your View with a lot of controls. When your view loaded completely, hide the Splash View and show your View.
In case you do something timeconsuming code with the controls in form constructor or while loading form you can write this.SuspendLayout(); before that code and this.ResumeLayout(); after that code. That prevents several time-killing layout operations.
Considering the information in question provided I wolud say:
Devide controls in possible groups (It's practically impossible that user needs all controls at the same time) and put them on separate Tabs of tab control.
Automatically (statially) load only controls on fisrt Tab, for others load them dinamically.
In this case, if the user doesn't need certain functonality will never switch to the Tab that contains it, so the controls of that functionality that user doesn't need will not be loaded, which will provided overall faster load time.
If there is a data that should be pushed on the controls, load it in async way where it's possible,
Hope this helps.
I have had a similar problem, but with many more controls than yours.
Considering that you have a relatively small set of controls, I think the culprit is the data access layer slowing down everything. (The loading of that grids and combos for example)
A simple action that can tell you many things is to move your data access to the form_shown event.
In Visual Studios (under the Solution Explorer), you can right click your solution/solution name and select properties at the bottom of the list. If you select "Configuration Properties," then go under configuration, you can select "Release" instead of "Debug." This will shave time off loading significantly.
Also, it is wise to avoid using "Thread.Sleep" in your code. This method is often used and mostly for poor code writers. About 10% of it is viable for particular circumstances, but I would avoid it at all cost.
Best way is to separate your solution to many layers
YourAppUI contains forms
YourApp.Controls contains controls
YourApp.BLL contains business logic
YourApp.DAL contains data access layer
Related
So, I'm writing a JSON viewer in WPF (I know there are a few out there, but I want more out of them and I want to use it as both a learning opportunity and a personal project). Since it's JSON, I want it to be able to hold vast amounts of data. I'm displaying everything in a TreeView, but the UX is starting to fall over when I get a lot of data. Not even a TON -- we're talking loading 89k of JSON here, though that 89k represents a little over 4000 nodes right now.
Ideally, I'd like to be able to display it all in a tree pre-expanded the first time the user gets there. However, I'm unhappy with how WPF is handling that many nodes in a TreeView and I'm not sure what to do about it.
I started with the VirtualizingStackPanel (IsVirtualized and VirtualizationMode="Recycling"). Those did a pretty good job of things, but it made scrolling wonky -- since new data comes in pre-expanded (via a style right now that sets each TreeViewItem.IsExpanded to true), the scrollbar tends to jump up and down while the user scrolls down in the window. On the bright side, the window loads up more-or-less instantly.
I know I don't have code in this post, but my question is more conceptual: what are some mitigating strategies I can use to fix this? Here's what I've come up with so far:
Load everything collapsed: Don't bother pre-expanding stuff. This is the route I am least enthusiastic about. Sure, it will help with particularly large data sets, but the small data sets will require manual expansion, and I'm suspecting that's the more common case.
Load everything collapsed if there are more than N nodes: This could work from a UX standpoint, though the value of N would be fairly arbitrary. I've seen the TreeView start to stutter after 790 nodes, so that apparently is a problem point; I'd have to do some more research into exactly where the breakpoint would be.
Lazy loading: Load nodes on-demand. Nodes would load very quickly -- I'm playing with JSON in memory, after all -- but it suffers from exactly the same problem as the first idea, loading everything collapsed.
Expand only the first node: Seems rather arbitrary, really. Plus, if the first node was particularly large, we're back to square one.
Expand everything in the background and show a loading screen or something: Would that even work? Can I push a UI thread to a background thread, or affect the UI on a background thread while I show a spinner or something? Never tried it -- my development career has always run into "This is the UI thread. Never hold it up." It never occurred to me that you could even have two UI threads. Does anyone know if you can?
Hide the control, load data into it, and show it when loading is done: Two problems with this. First, I'd have to figure out how I know when loading is done (I'm using binding here, so I'm not going through a method whose exit I can detect). Second, would it make any difference, or would it fall over as soon as it's un-hidden and starts rendering? That one I can look into.
Give up and take a vacation in the Carribbean: Because why not?
I am working on a real time trace logging application in wpf.I am reading logged data from a UDP port and converting it in terms of my modal class.The thing i am worried is, consider if the user keeps the application open for a long period of time,the application will be using a large amount of memory.I display the log information in a scrollable list,so the user has the provision to scroll up to and get to a previous log.I'm looking for a design approach so that i can deliver the best results with the optimal use of memory.So which is the best design approach for this kind of application ?
"Real Time" mean as soon as data is available Application should pick up it and display. No other way.
You can consider something like cleanup of the already previewed logging information if this is appropriate from user perspectives and load historical data on demand.
Also one of the possible solutions is to optimize LogInformationdata model so entities which you are displaying would require less memory, this could be significant improvement considering that a lot of entries are displayed and each single saved byte may result in MegaBytes of saved memory, so please share some code of entities which are bound to UI and indicate which fields/properties really need to be displayed to end user
For some kind of data you can implement Lazy Loading and request data from DB/file system on demand. For instance when an user opening Details form for a particular LogInfo entry in the UI list you are requesting advanced information like full description and so on, so you do not need to keep it always in memory whilst user do not request it by opening "More Details" form
If DB calls is high cost for your Applicaiton you can store some information on the file system in serialized format and load it On Demand in Lazy Loading manner.
Really it is hard to suggest something concrete without of knowledge of the Use Cases and standard workflows. So please provide more details how this applicaiton is used by an user so more ideas coudl come in.
One idea that might work is to add a "listener" that would see if the program was altered, or after lets say 5 minutes of seeming idle a popup would ask if you want to continue. It would then reconnect once the user clicks "ok"
Would that work? I am assuming that the memory use is on the log server.
It seems like your have two much data to display. You can use UI Virtualization. VirtualizingStackPanel can do what you want by not creating UI elements for all your log lines untill the user scrolls to it. A example would be too long for stackoverflow. There are plenty of examples on the web.
http://bea.stollnitz.com/blog/?p=338
On the other hand if you are memory requirements are too high just because there is too much log data. Consider writing it to a database on disk.
I am working on a large scale project where a custom (pretty good and robust) framework has been provided and we have to use that for showing up forms and views.
There is abstract class StrategyEditor (derived from some class in framework) which is instantiated whenever a new StrategyForm is opened.
StrategyForm (a customized window frame) contains StrategyEditor.
StrategyEditor contains StrategyTab.
StrategyTab contains StrategyCanvas.
This is a small portion of the big classes to clarify that there are many objects that will be created if one StrategyForm object is allocated in memory at run-time. My component owns all these classes mentioned above except StrategyForm whose code is not in my control.
Now, at run-time, user opens up many strategy objects (which trigger creation of new StrategyForm object.) After creating approx. 44 strategy objects, we see that the USER OBJECT HANDLES (I'll use UOH from here onwards) created by the application reaches to about 20k+, while in registry the default amount for handles is 10k. Read more about User Objects here. Testing on different machines made it clear that the number of strategy objects opened is different for message to pop-up - on one m/c if it is 44, then it can be 40 on another.
When we see the message pop-up, it means that the application is going to respond slowly. It gets worse with few more objects and then creation of window frames and subsequent objects fail.
We first thought that it was not-enough-memory issue. But then reading more about new in C# helped in understanding that an exception would be thrown if app ran out of memory. This is not a memory issue then, I feel (task manager also showed 1.5GB+ available memory.)
M/C specs
Core 2 Duo 2GHz+
4GB RAM
80GB+ free disk space for page file
Virtual Memory set: 4000 - 6000
My questions
Q1. Does this look like a memory issue and I am wrong that it is not?
Q2. Does this point to exhaustion of free UOHs (as I'm thinking) and which is resulting in failure of creation of window handles?
Q3. How can we avoid loading up of an StrategyEditor object (beyond a threshold, keeping an eye on the current usage of UOHs)? (we already know how to fetch number of UOHs in use, so don't go there.) Keep in mind that the call to new StrategyForm() is outside the control of my component.
Q4. I am bit confused - what are Handles to user objects exactly? Is MSDN talking about any object that we create or only some specific objects like window handles, cursor handles, icon handles?
Q5. What exactly causes to use up a UOH? (almost same as Q4)
I would be really thankful to anyone who can give me some knowledgeable answers. Thanks much! :)
[Update]
Based on Stakx answer, please note that the windows that are being opened, will be closed by the user only. This is kind of MDI app situation where way too many children windows are opened. So, Dispose can not be called whenever we want.
Q1
Sounds like you're trying to create far too many UI controls at the same time. Even if there's memory left, you're running out of handles. See below for a brief, but fairly technical explanation.
Q4
I understand a user object to be any object that is part of the GUI. At least until Windows XP, the Windows UI API resided in USER.DLL (one of the core DLLs making up Windows). Basically, the UI is made up of "windows". All controls, such as buttons, textboxes, checkboxes, are internally the same thing, namely "windows". To create them, you'd call the Win32 API function CreateWindow. That function would then return a handle to the created "window" (UI element, or "user object").
So I assume that a user object handle is a handle as returned by this function. (Winforms is based on the old Win32 API and would therefore use the CreateWindow function.)
Q2
Indeed you cannot create as many UI controls as you want. All those handles retrieved through CreateWindow must at some point be freed. In Winforms, the easiest and safest way to do this is through the use of the using block or by calling Dispose:
using (MyForm form = new MyForm())
{
if (form.ShowDialog() == DialogResult.OK) ...
}
Basically, all System.Windows.Forms.Control can be Disposed, and should be disposed. Sometimes, that's done for you automatically, but you shouldn't rely on it. Always Dispose your UI controls when you no longer need them.
Note on Dispose for modal & modeless forms:
Modal forms (shown with ShowDialog) are not automatically disposed. You have to do that yourself, as demonstrated in the code example above.
Modeless forms (shown with Show) are automatically disposed for you, since you have no control over when it will be closed by the user. No need to explicitly call Dispose!
Q5
Everytime you create a UI object, Winforms internally makes calls to CreateWindow. That's how handles are allocated. And they're not freed until a corresponding call to DestroyWindow is made. In Winforms, that call is triggered through the Dispose method of any System.Windows.Forms.Control. (Note: While I'm farily certain about this, I'm actually guessing a little. I may not be 100% correct. Having a look at Winforms internals using Reflector would reveal the truth.)
Q3
Assuming that your StrategyEditor creates a massive bunch of UI controls, I don't think you can do a lot. If you can't simplify that control (with respect to the number of child controls it creates), then it seems you're stuck in the situation where you are. You simply can't create infinitely many UI controls.
You could, however, keep track of how many StrategyEditors are opened at any one time (increase a counter whenever one is instantiated, and decrease it whenever one is closed -- you can track the latter using the FormClosing/FormClosed event of a form, or in the Dispose method of a control). Then you could limit the number of simultaneously opened StrategyEditors to a fixed number, say 5. If the limit is exceeded, you could throw an exception in the constructor, so that no more instances are created. Of course I can't say whether StrategyForm is going to handle an exception from your StrategyEditor constructor well...
public class StrategyEditor : ...
{
public StrategyEditor()
{
InitializeComponent();
if (numberOfLiveInstances >= maximumAllowedLiveInstances)
throw ...;
// not a nice solution IMHO, but if you've no other choice...
}
}
In either case, limiting the number of instantiated StrategyEditors seems like a temporary fix to me and won't solve the real problem.
I have a windows application in which a form is bound with the data.
The form loads slowly because of large data. I am also showing paging in form to navigate through the records.
How can I increase the performance?
Bottom line- your app needs to 'page the data' effectively.
This means, you will need to "lazy load" the data. The UI should only load and display data that it needs to show; therefore load additional data only when needed.
Since you didnt provide much of an information regarding your app and the data that you load.
So, lets assume that your app fetches 10,000,000,01 records.
Load your form
If, for instance your grid shows 25 records per page, so use TOP 100 to fetch the top 100 records, and fill in your first page and next four pages.
Upon each Next or consecutive 'Nexts' you can hit database to fetch next records. Note that, you will require some mechanism(ROW_NUMBER?) to keep track of the records being fetched, row numbers, etc.
This article discusses exactly what you are after and I am referring towards.
It's hard to say for certain without knowing more about your application, but the immediate thing that comes to mind is that if your dataset is large, you should be doing pagination on the database side (by constraining the query using row counts) rather than on the application side.
Databinding is a convenience feature of .NET, but it comes with a severe performance overhead. In general it's only acceptable for working with small datasets of less than a few thousand rows bound to a couple of dozen controls at most. If the datasets grow very large, they take their toll very quickly and no amount of tweaking will make the application speedy. The key is always to constrain the amount of memory being juggled by the data binding system at any given time so that it doesn't overload itself with the meta-processing.
Here are some recommendations:
Find out why you need to bring a large set of data. That much data displayed on the screen will not lead to a good user experience. If this is a search result or something, limit your search results, say 100, and let the user know that there is more but they need a more fine grained search criteria.
Check to make sure that your database query is well optimized and indexed and you are not bringing more data than you need to.
Assuming you are using a DataGridView, see if taking advantage of VirtualMode helps. Below description is from msdn and there is also a link to an example in there.
Virtual mode is designed for use with very large stores of data. When the VirtualMode property is true, you create a DataGridView with a set number of rows and columns and then handle the CellValueNeeded event to populate the cells.
If you are using some other control, you can see if that control provides a similar feature. ListView also has VirtualMode.
Fire up the SQL profiler to see what your applications is needing from the database. You may see some unnecessary calls, opportunities to trim your data needs and lazy load. Also debug and profile your application to see where you spend most of your time.
If you are using SQL server, implement paging using the Commaon table Expressions and ROW_NUBER(). This will allow you to get less data from the Sql server and definitely better performance.
I need to make an application in .NET CF with different/single forms with a lot of drawing/animation on each forms.I would prefer to have a single update[my own for state management and so on] function so that i can manage the different states, so that my [J2ME Gaming Code] will work without much changes.I have came to some possible scenarios. Which of the one will be perfect?
Have a single form and add/delete the controls manually , then use any of the gamelooping tricks.
Create different forms with controls and call update and application.doEvents() in the main thread.[ while(isAppRunning){ UPDATE() Application.DoEvents() }
Create a update - paint loop on each of the form as required.
Any other ideas.
Please give me suggestion regarding this
If its a game then i'd drop most of the forms and work with the bare essentials, work off a bitmap if possible and render that by either overriding the main form's paint method or a control that resides within it (perhaps a panel). That will give you better performance.
The main issue is that the compact framework isn't really designed for a lot of UI fun you don't get double-buffering for free like in full framework, proper transparency is a bitch to do with WinForm controls and if you hold onto to the UI thread for a little too long you'll get serious rendering glitches. Hell you might even get those if you do too much on background threads! :O
You're never going to get optimal performance from explicitly calling Application.DoEvents, my rule of thumb is to only use that when trouble-shooting or writing little hacks in the UI.
It might be worth sticking the game on a background thread and then calling .Invoke on the control to marshal back to the main UI thread to update your display leaving the UI with plenty of time to respond while also handling user input.
User input is another reason I avoid normal winform controls, as mobile devices generally don't have many keys it's very useful to be able to remap them so I generally avoid things like TextBoxes that have preset key events/responses.
I'd also avoid using different forms as showing a new form can provide a subtle pause, I generally swap out controls to a main form to avoid this issue when writing business software.
At the end of the day it's probably worth experimenting with various techniques to see what works out for the best. Also see if you can get any tips from people who develop games on CF as I generally only do business software.
HTH!