I am working on application which uses a DataGridView control. Since there is a lot of data I use the VirtualMode to use paging, but even with this feature this take a while to update DataGridView. So I created a control which spins and entertain an user. Unfortunately there are some issues with this solution, namely when the entertainment control spins the UI Thread does handle any of requests from it because it's so busy with this DataGridView.
What should I do to access the UI Thread even if it is so busy?
How do you do to "entertain" an user when you use the DataGridView or is there any main to prevent UI Thread from blocking by DataGridView?
btw. I know that Application.DoEvents probably could help, but I prefer not to use it.
Drop the priority of the DataGridView thread relative to the UI one or just throw in the occasional Thread.Sleep in the DGV data load function.
Combined with a little tuning of your page sizes that should sort it.
I'm not sure what your implementation looks like, so forgive me if you already know this: Setting the VirtualMode property to "true" doesn't make the DataGridView automatically populate itself via just-in-time loading. Rather, it just gives you as the developer the ability to do so. If you're using virtual mode but still populating the entire thing at once, then you really aren't gaining anything. Instead you'll have to implement your own paging algorithm. This is actually pretty easy to do. Please take a look at this MSDN topic for an example. Hopefully that helps!
Related
a lurker here, but time for my own question.
The question applies to this code: http://pastebin.com/dQKnSSpY I posted it on pastebin because it'll mess up this page otherwise :)
my question is why the GUI is quite lagging when I run this GUI. I've already tried several things, including DoubleBuffering, a seperate workerthread for adding the Controls and using BindingSource.
Nothing helped yet. I'm feeling a bit dumb, because usually my C# skills are okayish. (quite new to Windows Forms)
thanks in advance
I think your problem lies in the fact that you are creating controls inside Paint event. I'm little rusty now in Windows Forms, but i think Paint event is called when the control needs to redraw itself and that is controlled by the OS with WM_PAINT message. And that can happen frequently. Maybe you should try to add controls in the Form constructor and not in the Paint event.
It is a very simple change but it may help:
http://pastebin.com/FnXJCAUE
I took the Screen.PrimaryScreen.WorkingArea calculations out of your GUI updates and replaced them with a constant Integer that is calculated only once at the initialisation of GUI Class. This should help reduce the number of calculations performed each GUI draw and so speed up drawing in general, elsewise I didn't see anything immediately obvious in the code that would slow things down.
I am looking for advice and help regarding a specific use case of an application.
Here's the use case:
A user our our WPF application goes crazy and starts clicking all over, triggering a number of events before the first (or previous) event(s) have to finish.
Currently, WPF queues any and all clicks and queues them for sequential execution. Ideally we would like to queue up to 3 events and drop and disregard any and all clicks (user interactions) after the first 3.
What would be the best approach to solving this issue, what is the best practice for this use case. Any documentation, code and/or help would be much appreciated.
Since this really is a windows issue and not specifically a WPF issue, the only thing I can think of is hooking the message queue and discarding clicks within a certain time unless you write specific handlers into each control. The other option is to write the application such that feedback is provided to the user during an operation and input is disabled.
What does WPF use to capture mouse and keyboard input?
If you'd use MVVM all UI actions are bound to ViewModel commands or properties. In the ViewModel you'd have full control over how many and how frequently you want to process what comes from the UI. It will probably involve some sort of producer consumer queue.
Also if your user actions block the UI, you need to process them outside the UI thread as much as possible.
In an application that I'm writing I have to load a lot of data in a listview after I push a certain button. Because this might take a while, I want to show a simple loading-screen to the user.
I did this by creating a very simple form with 1 label on it. I do a Form.Show() before I start fetching the data, and a Form.Close() once it's finished. This works partially: I get the loading screen, it closes at the right time, but as you can see the label isn't displayed.
I know I should program this loagind screen-problem with the help of a BackgroundWorker, but I'm not a very experienced C# programmer so if I could just somehow force the label to display I would be more than happy.
Is it possible to force this label to display immediately, or do I have to find another solution?
The UI Message pump has no time to update the label / refresh the screen since the loading process takes up all resources.
You can try to force the update of the label, by calling Application.DoEvents(). Although, using 'Application.DoEvents' is imho a 'code-smell', and thus indicates that the design is not that good. So, it should be avoided.
Therefore, using DoEvents is surely not the best solution to this problem. It is merely a symptom-fix.
You've mentionned the best solution already yourself: use another thread to load all the data. (You can indeed use a BackGroundWorker for this purpose, since this will abstract away a lot of plumbing code).
BackgroudWorker is very easy to use , even c# is very powerful and simple langugage
See Here
i am almost sure that , you would not need any more help with BackGroundWorker but if you have any query , you canm always post on SO ?? Collabartive Intelligence is what SO is?
My program consists of a large graphing UI control that I need to spend about 15 seconds re-loading every once in a while. Because the updating code works primarily with the UI control (maybe 90% of it actually sets properties on the control), it would make sense to me to actually let the UI thread handle that. I really don't want the control to visually re-paint while it is loading in a separate thread from the UI.
I also want a progress bar to update as well that lives in the status bar of the same application window. Is there a way to break the rule in this case and re-paint only the progress bar, or should I just open a new application window for the progress bar to live in?
What would you do in this particular case?
If you can break your primary task (ie. updating the graph) in many steps, you can perform each step as a separate dispatcher message. This will allow other messages to be processed, including giving you the ability to update progress information.
The basic pattern is:
Invoke your primary task, passing in zero for the step.
Perform the step.
If there are more steps, queue another message, passing in step + 1.
You can then add in progress updates at the appropriate points in your code.
PS. Not saying this is your best option - hard to tell without knowing all the details. But this is an option.
It is not really true that there is only one UI thread in an application, it is just that most windows applications only ever create UI objects in one thread so this thread becomes "the" UI thread in the application. It is easy to understand why - this makes the code simpler to understand, and protects us from implicit thread binding issues between controls.
This suggests a possible idea, should it prove impossible to improve the speed of updating the control (which is what I would suggest to do first). Create the UI control on a separate thread. You need to make sure that the thread is suitable for UI, that is to say the threading model is STA, and that it will pump messages and not die before the control is destroyed. I don't know if you need to create the parent window in the UI thread as well, or just the control but it may be worth experimenting here.
Find a graphing UI control that is more efficient. Unless the UI thread yields to the message loop any other updates won't happen (and it will slow down your graph control's updates).
I would suggest using a progressbar in a new window (without the form headers). Make it paint the progress bar by reading the shared properties of a graph control. this way you can avoid the thread blocking (sluggish loading).. And it gives you good visual experience (progressive painting on both the controls).
I'm looking at creating a tabbed interface which has user controls (possibly written by plug-in developers) within a tabbed or MDI interface. These plug-in controls could unintentionally freeze their GUI thread, and I'd prefer that they not influence user controls in other tabs. Much like Google Chrome creates a process for each tab; but in this case, just threads.
Or perhaps even an MDI interface where the child MDI forms are owned by separate threads?
I've found that while I can run multiple GUI threads at once, the Form level is where they MUST be separated. Any workarounds/ideas?
For those saying this shouldn't be needed, I call bullshit. Google's Chrome browser runs tabs in separate processes for security and UI reasons. I'm merely trying to duplicate this behavior. When the people writing the user controls are sucky plug-in developers, this is important.
No it is not possible to do this in the way you are describing. A control which is owned / affinitized to another GUI thread cannot be directly contained within a control which is owned / affinitized to a different thread in such a way that it's paint function runs on the other thread.
The right way to fix this situation is to write UserControls that don't perform long-running tasks on the UI thread. If the control is blocking and waiting on some computational task, fix that. Make that task run in the background, and have the control display some non-compute-intensive content until it's done. If that task freezes, the control will be frozen in its "I'm waiting..." state, but it won't intrude on the rest of the UI.
If you're using a third-party control that you can't fix, well, in the immortal words of Jay-Z, I feel bad for you, son.
For the most part, controls shouldn't be performing any processing. Their purpose is to provide interactivity between the user and the application. For example, it is not the job of a button to fetch data from a database and present it to the user. That being said, hopefully you are doing your processing in a controls event handler, such as the Click event on the Button control. In your event handler, you can prevent the UI from appearing "hung" by processing tasks in a background thread. The BackgroundWorker is often useful in these situations.
I suggest reading up on Threading. The Microsoft® .NET Framework Application Development Foundation book has a section on threading (even if no other certification books are read, I at least recommend all .NET developers read this book). Just remember not to update the UI from a child thread. Read an example on how to make a thread-safe call to Windows controls if you're not familiar with this approach.
Instead of having or owning different GUI threads, you should view the whole issue from a different angle. Why would you want a thread associated to tab's child control to be freezed? If it does freeze and everything else feezes too, threading aside, that's not done right from ground up.
What JaredPar pointed out is correct, but that doesn't mean you cannot achieve what you want. I assume you want stuff running within a tab to continue running/stopping without affecting other controls and user-experience.
I've done it before in a complex WinForm app. Here are some readings which might give you more insights:
Threading out tasks in a C#.NET GUI
Thread and GUI
Updating GUI from Other Threads in C#
Advanced Techniques To Avoid And Detect Deadlocks In .NET Apps