Annoying slow responsiveness of form whilst populating combos on background thread - winforms

I have a form with 2 tabs. The first tab is boring, the second tab (unseen as default to the user) contains many comboboxes.
Using the FormLoad() event I populate a combobox on the second tab (with around 11,000 items/strings) on a background thread. The sql command to do this is also asynchronous.
Now, in theory this should mean that when the user finally gets round to clicking the second tab (whether that be in 10 seconds or 10 hours) they should be instantly presented with a nicely populated control - but there is ALWAYS a 4 second delay. I just don't get it! If all the heavy lifting is done via the background thread (the whole reason for using them in the first place!), why the heck is my application still slow and unresponsive when the user clicks that darn second tab??!!?!
*Bearing in mind you have to give the application a chance to fill the combo in the first place, plus I know when it's finished populating as the backgroundWorker1_RunWorkerComplete() method fires and sends a debug message to tell me all work has finished.*
Any help will be much appreciated....

11,000 is a lot! The work has been done to populate the comboBox items on the background thread, but the form still has to show all those items. This means the UI thread has to render a proportion of them (or all of them) to the UI (into memory) ready for scrolling; this is what is taking time.
I would suggest overriding the ComboBox control and handling the scroll event yourself. This way you can load a subset of the entire list sequentially when you need them (if that is possible in your case). This will prevent the four second delay you speak of.

Related

Best way to display realtime queue data from database in grid

I have a client-server VB.NET/SQL2008 application which, among other things, keeps track of people who are waiting in a queue. The records for the queue are all updated via the application but they are added/removed on different workstations.
I need to display the queue of people in a grid (could do a multi column listbox if it would add any benefit) and have it automagically update when the queue changes. I don't need it to be real-real-time but I would like the people to show up within a few seconds. I currently have a datagrid bound to the data and I have a timer which is refreshing the datagrid every few seconds. However I'm thinking there must be a better way to do it.
The one thing I don't like is how the grid flickers when it refreshes and if someone double-clicks to select a record exactly as it's refreshing it selects the first person in the list and not the one selected.
I've done some research and it seems like one option is SQL Dependency - however from what I've seen people say it's difficult to set up and get working and "fragile".
Any help is appreciated!

How to make UI elements load without freezing? (WPF)

I have a treeview and a textbox. As I type in the text box it updates the tree view in real time (filtering by what I type and matching against the objects in the tree view).
The problem is it starts freezing a bit as I'm typing in the box. ie. while the treeview is updating the text box freezes. I have put the logic that populates the treeview in another thread hoping this would make it run a bit faster - which it did, but not enough. I believe it is the actual UI updating which is causing the responsiveness to diminish.
What are some ways that I can tackle this problem? Is it possible to have different UI elements (in this case, the treeview and the textbox) handled in different threads - rather than just the logic which is the case now?
Thanks
Your problem is that only one UI thread exists!
A possible solution to your problem is to filter the treeview after a few milliseconds after the user has made ​​a text input.
Another possibility is to make the filtering in a separate task and the result of the Treview reassign.
I hope this helps you with your problem.

Keep form size when moving, if changed from another thread?

By experiment I found that Resize event is fired when Move is performed. Not only that, but Move action also preserves resize factors (so literally Move=Resize). In practice it means, when the form is being Moved (i.e. by user), and if another thread resizes it through BeginInvoke, it will get its original size (the one it had before movement started) when the next Move event happens.
Business use case/example: user opens a screen with dynamically sized ListBox, which contains dynamic list of items, whose population may take considerable time. Assuming loading takes place in a parallel thread and then BeginInvoke is called to update DataSource. When DataSource is updated, form size should change to accommodate all items on screen, if possible (if not, pagination will occur). With default approach, size update will have no effect if user was moving the form across the screen (to another screen would be best example) when the list finished loading, as it would automatically revert to original size.
Question: is it possible to somehow override Move or Resize behavior to consume that new size and not revert to the original one? Should I look into WndProc hacking?
Not sure if my answer would be useful 3 months late, but I got around this by handling the Form.ResizeBegin and Form.ResizeEnd events. These are called respectively whenever the user starts and stops dragging around the form on the screen.
In ResizeBegin event handler
beingMoved=true;
In the method called by BeginInvoke:
if(beingMoved)
needsExplicitSizing=true;
In ResizeEnd event handler:
beingMoved=false;
if(needsExplicitSizing)
this.Size = new Size(width,height);

WPF AutoCompleteText - Solution that doesn't lag / lock UI on popup generation

I have tried about 4-5 different WPF solutions so far, including the WPF Toolkit and gradonz.actb (my favorite option) but every single one seems to be lagging when creating the dropdown. Once the dropdown is there, the data loads extremely fast, but on initial creation it is lagged and locks my UI. And this is not just a one time thing, each time it is created it appears to have a second or two lag / UI locking (I am assuming while it creates the object in my tree).
In advance I do know it is not my datasource as I have traced it and it never takes under 10 milliseconds to return to the search providers. I am also returning just 20 items max to the provider, so there is no reason that I can see for this delay. The problem is when it generates the list to show, and it happens on all of the solutions I have found.
Even if you know a licensed one that works well, I am willing to spend to solve this.
I appreciate any help
Anthony Greco
The issue was the popup class was lagging on show and it popped it up each time a new result started. A hack around this was popup on load, and when we don't need it, set the height to 0. Not ideal, but after 4 hours, at least it works.

Adding controls to winform while allowing user to enter input

I have a WinForms data entry form that will have upwards of 1500 questions. I have the questions broken into sections, and each section will have an unkown number of questions. Each section is its own user control and has rows (2 panels, 2 labels, a textbox, and another user control) created and added dynamically for each question. The section controls are then added to the form.
My problem is that the process takes a lot of time, even with using TPL (Task Parallel Library). I would ultimately like to create/add the controls and allow the user to start entering data at the same time. The controls are going into a scrollable panel. While the user is entering data, that data will need processed on a local database...so more threading could be necessary.
I have tried working with TPL, which I am new to, by having all the controls added to a list during processing and then sorted and added to the form after the Parallel.ForEach was complete...takes about 20 seconds for over 1200 questions.
I also tried utilizing a BackgroundWorker component. Using the BWC seems to be the faster of the two, but there is a race condition for the ProgressChanged() eventhandler and not all controls get added...not to mention the way the form looks with all the rerendering.
Am i just using TPL wrong? What's the best way to go about this? Is there another way or do I just make the user stick out the wait?
Thanks
Am i just using TPL wrong? What's the best way to go about this? Is there another way or do I just make the user stick out the wait?
Most likely, you can use TPL, and get the same response time as BW, but a nicer API for this type of operation.
The trick here is to get a TaskScheduler setup for UI interaction, and then use the Task class to push the controls back onto the UI thread as they're ready. I have a blog post on this specific subject which shows how to get a TaskScheduler setup to use with UI threads.
However, I would recommend keeping these in memory and pushing them in batches, to avoid constantly re-rendering the UI. This is likely to be an issue no matter what you're doing.
That being said - I'd question your overall visual design here - if you're trying to display over 1200 questions to the user, some form of paging is probably a much nicer approach than a huge scrollable container. If you page these, you could load and process the first few (which is probably near instantaneous, since you mentioned you can process about 50 questions/second), and then continue loading the others after the first few questions have been displayed.

Resources