i have a stored procedure which is taking 10 seconds to pull 30 records from a table after long processing.Each datalist item has many controls within which are to be data bound while binding those 30 records to the datalist, which is also taking a bit long.
I want to know if we can assign this job to a thread??
Please help,thanks in advance!!
Each datalist item has many controls within which are to be data bound
while binding those 30 records to the datalist, which is also taking a
bit long.
Binding a UI control, shall always be on the UI thread
I want to know if we can assign this job to a thread?
Simple answer is no for a UI control
Option for you would be an in memory data collection can be updated on a thread, but you need to make it thread safe either using a thread safe collection or a using a construct like lock
Final Data binding will always be on UI thread, else it will lead to exception
Related
I have a list of Customers and I update my DataGrid's ItemsSource to contain the customers list.
The problem is that after changing the ItemsSource, the thread update all binding targets to the values in each customer object, and this action freezes the UI for more than 30 seconds.
To solve this I tried to change the ItemsSource property in another Thread but the new thread can not access the datagrid control which owned by the UI thread.
If I put the ItemsSource changing code in Invoke methode the UI will freeze again.
//The following code is handled in another thread
// Geting a list of Customers
List<Customer> customers = manager.AllCustomers.SearchCustomers(fName, lName, address, city, tz, phone);
//Changing the DataGrid ItemsSource
Dispatcher.Invoke(() => customersSearchResultsDG.ItemsSource = customers);
//UI Thread is freezing until ItemsSource Changing complete
p.s
The amount of time it thinks not really bother me because I created a loading animation control.. but the freezing makes the animation stuck and that is what i'm trying to fix.
When the UI thread in a WPF Application is busy, the UI will appear to freeze. There is nothing that can be done about that, but to avoid this situation, we typically do as much long running work as possible in background threads. However, as you have discovered, you cannot manipulate UI elements from a background thread, so there is only so much that we can do.
Other things that we can do to minimise the amount of time that the UI thread is busy is to use Virtualization, container recycling, freezing resources and/or optimise used Templates. You can find out more about this from the Optimizing Performance: Controls page on MSDN.
However, with the small number of items in your collection, it would seem to me that either you are loading and/or preparing your data extremely inefficiently, or you have incredibly large and complex DataTemplates to define your items. The links provided above should help you if your problem is the latter.
I have a list (of type class). It has several rows..44000 for example, and I need to bind it to a datagridview in c#. I wanna do it without taking the control of the UI from the user. Even when I am using a background worker, the title bar says not responding.
its as simple as
dataGridView1.DataSource = bars; where bars is a bindinglist which has 44000 rows.
This single line is clogging up all the UI and the time..
Any ideas?
My suggestion is on binding smaller batches with the ones in view or will be near in view only. And dynamically as the user scroll, update this binding list.
There isn't a perfect solution as the size of your list is so long, binding the whole thing one way or the other will yield performance hit.
I want to be able to add items to a Data grid at a fast rate without causing UI delay.
Here is what I am doing now:
I am using an ObservableCollection that is bound to the data grid.
I use a background thread that loops and calls Invoke on the current dispatcher only when inserting/removing from the observable collection. Calling BeginInvoke instead has undesirable results.
I know that invoking that much on the dispatcher is causing the delay but I don't know what else to do. I have used background workers before but I don't think that applies to my scenario.
What can I do to keep the UI responsive?
Batch the updates -- the background thread could add items to a queue and you can periodically refresh your bound observable collection by invocation. Take a look at the System.Collections.Concurrent namespace if you need to handle multi-threaded producers
A major weakness in your design is that by binding to an ObservableCollection, you are causing the UI to render every item that get's added to the list (possibly thousands) - even if at the end of processing there are only 10 items which need to be rendered.
I saw huge improvements by changing the ObservableCollection to a List, and refreshing the DataGrid manually at the end of processing - this way the UI only ever needs to process 10 items. I found that this change caused a 50% performance gain, as well as allowing the UI to be 100% responsive while the List is being processed.
If you are processing the list for a long time, and need to show live changes, you could refresh the DataGrid every 100 items. This would show results with about 0.5 second accuracy which should be close enough.
I've got an SQL query that returns hundreds of rows, and I need to add them to a WinForms DataGrid in a way that will still allow the user to view/scroll the DataGrid as the rows are added.
Currently I'm using a BackgroundWorker thread to execute the SQL statement and loop through the rows in a DataReader, before using Control.BeginInvoke to pass each new row back to the UI thread where it is added to the DataTable that's bound to the DataGrid. This isn't really having the desired effect (it takes a little while to update the DataGrid, and then after it does one update the UI becomes unresponsive).
Is there a way to do what I want, and if so how?
Edit: I've added a thread.sleep to the worker thread as it loops through the datareader, which stops the UI from becomming unresponsive after the first update, but it's still not as responsive as I would like it to be (scrolling is a bit jumpy as adding a row in the ui thread seems to steal focus).
Have you looked at virtual mode for DataGridView controls? It can offer some way of iterating only the rows you need to view (i.e. only get data when the user scrolls).
See: http://msdn.microsoft.com/en-us/library/ms171622.aspx
PS: DataGrid is old, try DataGridView :)
Currently I'm using a BackgroundWorker thread to execute the SQL
statement and loop through the rows in a DataReader, before using
Control.BeginInvoke to pass each new row back to the UI thread where
it is added to the DataTable that's bound to the DataGrid.
It seems that you are using Dispatcher to update the UI. That's not a good idea. Using datagrid in multithreaded environment is tricky. I have published a template here. It covers a possible approach on using datagrid in multithreaded setup.
http://www.codeproject.com/Articles/1086714/A-Template-For-Using-Datagrid-in-Monitoring-UI
I have a form with two panels(top, bottom), each panel contains grids. Basically, it's a Master-Detail form where selecting a row from the top grid would show details in the bottom grid.
Binding the data to the detail grid is taking some time. Since binding is done on UI thread, it blocks the thread and therefore the user cannot select another row from the master grid until the binding is done.
Please note that by binding I don't mean getting data from data source. It's the actual binding that's taking longer as it does a lot of data massaging. How can I keep the UI thread free while the detail grid is doing it's binding?
Thanks a million.
You can't. The update of the UI has to be performed on the UI thread.
You may be able to speed up the binding by using things such as BeginUpdate/EndUpdate which is available on some controls but as you don't specify what you are using I can't say if that's available.
You can use a background thread to perform your data retrieval, then use the UI thread to display it.
If I were you, it sounds like you are dealing with a LOT of data, and I would separate all the "massaging" you can into a separate thread process.
So maybe for example when a master record is created, you "manually" spin off the detail data in a background thread to another dataset and do the massaging, then just bind the resulting dataset to the grid. That way the only thing taking place on the UI thread is just the UI binding.
Ultimately if it's taking that long, you may be approaching a critical point in your application where you need to manually do what you need to do in code rather than using the out of the box data binding features in .NET.
Finally I found the solution. The solution doesn't include multithreading to start with. As I said that the delay was in binding the grid meaning the main thread was held, we couldn't do much. So the solution is to bring delays. When user selects the master row, a timer ticks off for a certain time. If another request is made before the time is expired, timer gets restarted. This is we ignore all calls that are made because user was clicking or selecting rows too fast. Once timer is expired, I take the selected row and display data. Simple and elegant solution.