UI thread stalls on loading and updating a RadGridView object - asp.net

Afternoon all,
I'm currently profiling a rather large C# WPF app, trying to eliminate a few performance issues. One involves a 5-8 second stall that occurs when switching to a particular (rather large) UserControl. I've narrowed this down to a RadGridView contained in this UserControl that's taking a long time to load and update itself, stalling the UI thread and making the entire application unresponsive. Obviously, we'd like to eliminate this stall if possible.
I have tried stripping away any custom styles and DataTriggers on the grid, but while this acted to reduce load on the UI thread in general, the stall still remained, seemingly undiminished. Through ANTS Profiler, it seems that the measuring and layout of the grid is mostly to blame, along with some loading of XAML templates. With no grid rows, the UserControls loads significantly faster, and it seems that adding just a small number of rows is enough to bring about this stall. The grid has virtualization enabled for rows and columns, but this doesn't seem to help. The call graph is tremendously deep when examined, and it seems to be calls that raise update notifications, update layout, load XAML and, above all, measure child FrameworkElements that are to blame.
For a couple of potential solutions, I'm thinking about keeping the UserControl in memory but hidden to reduce the costs of switching to it, or populating the grid, perhaps incrementally, well after the UserControl has loaded. There might be a lot of work with the former, as the control subscribes to a number of things, which would need to be connected to, disconnected from and reconnected to as appropriate. The latter might also involve a fair bit of work, but might be a better solution, because then at least we could try to mitigate the stalling ourselves, or at least warn the user when it was occurring.
If the problem persists, we're likely to ask Telerik to have a look at it, but I thought I'd ask here first in case anyone has encoutered such an issue before (not necessarily with RadGridView, even) and found a solution of some description.
Cheers.

The problem is you need a collection that implements ICollectionChanged properly.
Try this after adding all records to your source collection (one which should NOT raise any CollectionChanged events after each add), it works:
public void AddRange(List<TValue> values, int startingIndex)
{
// add all the items to your internal list, but avoid raising events.
// now raise CollectionChanged with an IList type.
CollectionChanged?.Invoke(collection, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, addedValues, startingIndex));
}
Notice we're passing IList<TValue>, NOT TValue. When it sees a list, it adds them ALL before processing. The startingValue is usually the .Count of the list before you started adding items.
Steps:
Subclass a collection type that doesn't already implement INotifyCollectionChanged. Plenty of open source examples are out there.
Add the method above and use it after you've added your items.
My RadGridView is binding against a QueryableCollectionView which uses this list as its SourceCollection. I don't know if you can bind against this list directly.
One strange behavior with RadGridView is that if you add say, a million records this way, it WILL be quick, but all the new rows will be blank, and you can watch RadGridView slowly populate them with data from the topmost new item down. My solution to this is to bind against QueryableCollection and set its PageSize sufficiently small so the users don't see this.

Related

How to most correctly / efficiently refresh an Item whose source has changed?

I have a loaded qml file from the file system that changes, however since the first time it is loaded it is also cached, it doesn't refresh even if the Loader is "reset" via setting the source component to undefined.
A similar questions has been asked before, however I'd like to go further for a few reasons:
the accepted answered there suggest the use of engine->trimComponentCache() which unfortunately works only once and then stops, no further updates are reflected
in the comments below, the OP suggests that engine->clearComponentCache() works, and indeed it does, each and every time. However the documentation for this method has me a little uneasy in regard with its usage:
This function causes the property metadata of all components
previously loaded by the engine to be destroyed. All previously loaded
components and the property bindings for all extant objects created
from those components will cease to function.
This certainly sounds ominous, especially the part in bold, since I am not reloading my entire application, it is just a tiny part of a rather big application, which needs to remain in tact while at the same time refreshing that particular external qml file to reflect its changes.
The second part thou sounds a bit more promissing:
This function returns the engine to a state where it does not contain
any loaded component data. This may be useful in order to reload a
smaller subset of the previous component set, or to load a new version
of a previously loaded component.
Once the component cache has been cleared, components must be loaded
before any new objects can be created.
So it does give the impression that this method can be used to only reload a subset without breaking the existing code. However, even if that is the case, it will involve a lot of extra work to rebuild all caches for newly instantiated objects, rather than simply cleaning the cache for the particular qml source that changes.
Additionally, I've been thinking about a more complex solution, involving the creation of a custom QML element, which is essentially a wrapper around a whole new QML engine that renders to an FBO and displays the output as an object in my "main" engine, thereby completely isolating the two engines. However I am not all that keen on doing all that extra work, and introducing the overhead of another whole running engine.
So any ideas?
Until someone comes with a better solution, I have meanwhile discovered that trimComponentCache() fails only if the clearing, trimming and resetting happen sequentially, that is in the same event loop cycle. It works every time if the event loop is allowed to spin in between, so I went for this solution, which works every time:
Timer {
id: updater
interval: 1
repeat: true
property int s: 0
onTriggered: {
switch (s) {
case 0:
loader.sourceComponent = undefined
++s
break
case 1:
Aux.trim()
++s
break
case 2:
loader.source = "file:/d:/Rect.qml"
s = 0
stop()
}
}
}
So the update is issued by starting the timer, it will clear the loader in one cycle, trim the cache in the next, and reload the source and stop in the last, resetting both the loader and its state.

SignalR and SqlDependency refreshment issue - ASP.NET

I have a table in MSSQL database, and I have an ASPX page, I need to push all new rows to the page in a descending order. I found this awesome tutorial which is using SignalR and SqlDependency and it shows only the last row descarding the previous rows which have been added when I'm online, it does that because it has a span element to show data and every time it overwrites this span, so I modified the JavaScript code to append the new data and it works fine.
The problem now is when I refreshed the page for the first time, I'll get the new rows twice, and if I refreshed the page again I'll get the new rows triple .. and so on.
The only solution is to close the application and reopen it again, it looks like reset the IIS.
So, what can I do to avoid duplicating data in the online show?
It is not a SignalR issue, that happens because the mentioned tutorial has a series of mistakes, the most evident being the fact that it continuously creates SqlDependency instances but then it trashes them without never unsubscribing from the OnChange event. You should start by adding something like this:
SqlDependency dependency = sender as SqlDependency;
dependency.OnChange -= dependency_OnChange;
before calling SendNotifications inside your event handler. Check this for some inspiration.
UPDATE (previous answer not fully accurate but kept in place for context)
The main problem here is that this technique creates a sort of auto-regenerating infinite sequence of SqlDependencies from inside instances of Web Forms pages, which makes them unreachable as soon as you page has finished rendering. This means, once your page lifecycle is complete and the page is rendered, the chain of dependencies stays alive and keeps on working even if the page instance which created has finished its cycle. The event handler also keeps the page instance alive even if unreachable, causing a memory leak.
The only way you can control this is actually to generate these chains somewhere else, for example within a static type you can call passing some unique identifier (maybe a combination of page name and username? that depends on your logic). At the first call it will do what currently happens in your current code, but as soon as you do another call with the same parameters it will do nothing, hence the previously created chain will go on being the only one notifying, with no duplicate calls.
It's just a suggestion, there would be many possible solutions, but you need to understand the original problem and the fact that it is practically impossible to remove those chains of auto-regenerating dependencies if you don't find a way to keep track of them and create them only when necessary. I hope that part is clear.
PS: this behavior is very similar to what you get sometimes with event handlers getting leaked and keeping alive objects which should be killed, this is what fooled me with the previous answer. It is in a way a similar problem (leaked objects), but with a totally different cause. The tutorial you follow does not clarify that and brings you to this situation where phantom code keeps on executing and memory is lost.
I got it, although I don't like this way absolutely, I have declared a static member in the Global.asax file and in the Page_Load event I checked its value, if it was true don't run a new instance of SqlDependency, otherwise run it.
if (!Global.PageIsFired)
{
Global.PageIsFired = true;
SqlDependency.Stop(ConfigurationManager.ConnectionStrings["db"].ConnectionString);
SqlDependency.Start(ConfigurationManager.ConnectionStrings["db"].ConnectionString);
SendNotifications();
}
Dear #Wasp,
Your last update helped me a lot to understand the problem, so thank you so much for your time and prompt support.
Dear #dyatchenko,
Thanks a lot for your comments, it was very useful too.

UITableViewCells and NSURLConnection

I have a custom UITableViewCell, and when the user clicks a button i make a request to a server and update the cell. I do this with a NSUrlConnection and it all works fine (this is all done inside the cell class) and once it returns it fires a delegate method and the tableivew controller handles this. However when i create the cell in the tableview, i use the dequeue method and reuse my cells. So if a cell has fired a asynchronous nsurlconnection, and the cell gets reused whilst this is still going on, will this in turn erase the current connection? I just want to make sure that if the cell is reused, the actual memory that was assigned to the cell is still there so the connection can fulfil its duty??
You can customize the behavior of a UITableViewCell by subclassing it and overriding the -perpareForReuse method. In this case, I would recommend destroying the connection when the cell is dequeued. If the connection should still keep going, you’ll need to remove the reference to it (set it to nil) and handle its delegate methods elsewhere.
It's never a good idea to keep a reference of a connection or any data that you want to display in a cell, no matter how much of effort you put into it afterward to work around to arising problems. Your approach will never work reliable.
In your case, if the user quickly scrolls the table view up and down, your app will start and possibly cancel dozens of connections and yet never finishes to load something. That will be an awful user experience, and may crash the app.
Better you design your app with MVC in mind: the cell is just a means to display your model data, nothing else. It's the View in this architectural design.
For that purpose the Table View Delegate needs to retrieve the Model's properties which shall to be displayed for a certain row and setup the cell. The model encapsulates the network connection. The Controller will take the role to manage and update change notification and process user inputs.
A couple of Apple samples provide much more details about this topic, and there is a nice introduction about MVC, please go figure! ;)
http://developer.apple.com/library/ios/#documentation/general/conceptual/devpedia-cocoacore/MVC.html
The "Your Second iOS App: Storyboards" also has a step by step explanation to create "Data Controller Classes". Quite useful!
Now, when using NSURLConnection which updates your model, it might become a bit more complex. You are dealing with "lazy initializing models". That is, they may provide some "placeholder" data when the controller accesses the property instead of the "real" data when is not yet available. The model however, starts a network request to load it. When it is eventually loaded, the model must somehow notify the Table View Controller. The tricky part here is to not mess with synchronization issues between model and table view. The model's properties must be updated on the main thread, and while this happens, it must be guaranteed that the table view will not access the model's properties. There are a few samples which demonstrate a few techniques to accomplish this.

ASP.NET Wizard control downside

I am in the process of evaluating the ASP.NET Wizard Control. Where we need to collect data from different steps, validate data and towards the end I should be able to show a data summary.
I would like to know from the group if anyone has used this control and what issues they faced. Are there any usage limitations with this control?
The Wizard control can save you a lot of plumbing time if you use it well - however, learning to use it well may cost you more than the plumbing time that you save. If you plan to reuse it, then the initial investment in learning about its idiosyncracies may be worth it.
I have built a wizard in which the steps displayed in the side bar depend on which step you are at (and on what you have done to that point). It follows that the step you go to when you press Next or Previous is also determined dynamically.
To implement this, I read a lot of stuff about dynamically disabling steps, hiding steps, and adding and deleting steps. The latter led me into deep water with the ViewState. For what it is worth, here is my basic approach:
You can control which steps are visible in the sidebar by setting the step ID (and Title if set) to an empty string e.g. I have the step names in arrWizardSteps() and my steps defined as integer constants, then use
For i = intCREDENTIALS To intADDITIONAL_INFORMATION
Wizard1.WizardSteps(i).ID = IIf(Wizard1.ActiveStepIndex < i, "", arrWizardSteps(i))
Next
If the steps are relatively independent, you can handle the SideBarButtonClick, PreviousButtonClick and NextButtonClick events by calling the same routine, which you construct to handle leaving the current step, and entering the next, irrespective of which button you clicked to make the transition. For example, the routine might store the data captured by the controls of the current step, and load some data into the controls of the next step.
If you do handle these events, you probably need to handle changing the ActiveStepIndex yourself. The wizard will increment/decrement the ActiveStepIndex (depending on which button was pressed) if you don't change it (unless you set e.Cancel=true in your handler where e is the WizardNavigationEventArgs argument to the handler).
If your code for hiding steps needs to know the destination step then you need to put that code in PreRender, since at that point the wizard will have moved to the next step and you will know what it is.
Personally I don't like the wizard control. Its quite rigid and I didn't find it very nice to work with. Since then I have used the MultiView control inside and UpdatePanel with User controls in each View for each step for my wizards. This way it can be completely flexible.
With the MultiView approach you can also see all steps of the wizard easily in the designer.
This is just my option on the control though, I didnt give it much of a chance on its first visit.

howto avoid massive notification in DataBinding

I guess it's quite a common problem in databinding scenarios.
What do you usually do, if you are running a batch update and want to avoid that a propertychanged-dependend calculations/actions/whatever are executed for every single update?
The first thing which usually comes to my mind, is to either introduces a new boolean or unhook/hook the eventhandler, ...
What I don't like about this approaches is:
they introduce new complexity (has to be maintained, ...)
they are error prone, because you have to make sure that a suppressed notifications are sent afterwards
I'm wondering if somebody addressed this problem already in a more convenient way that is more easy to handle?
tia
Martin
Edit: not to missunderstand me. I know about the things .NET provides like RaiseListChangedEvents from BindingList, ... They are all addressing the problem in more/less the same way as I described, but I'm searching for a different way which doesn't have to listed drawbacks.
Maybe I'm on the wrong track, but I though I give it a try here...
There isn't a single one-size-fits-all solution, unfortunately. I've applied or seen the following solutions:
There are two singals. One signal is emitted when the change comes from a user action, the other always fires. This allows to distinguish between changes in the UI and updates by code.
A boolean to protect code
The property event framework stops propagating events automatically when a value didn't really change.
A freeze/thaw method on the signal or the signal manager (i.e. the whole framework)
A way to merge signals into a single one. You can do N updates and they get collected into M signals where M <= N. If you change the same property 100 times, you still only get 1 signal.
Queuing of signals (instead of synchronous execution). The queuing code can then merge signals, too. I've used this with great success in an application that doesn't have a "Save" button. All changes are saved to the database as you make them. When you change a text, the changes are merged over a certain time (namely until the previous DB update returns) and then, they are committed as a single change.
An API to set several values at once; only a single signal is emitted.
The signal framework can send signals at different levels of granularity. Say you have a person with a name. When you change the name, you get two signals: One for the name change and one "instance field changed". So if you only care "has something changed", then you can hook into the instance instead of all the fields.
What platform? The post makes me think .NET.
What is the underlying objects? For example, BindingList<T> as a source allows you to disable notifications by setting RaiseListChangedEvents to false while doing the update.
Other than that (or similar); yes, disconnect the binding during big updates
The easiest route to take is to use the BindingSource component for your data binding. Instead of binding your controls to a particular object (or IList), use that object as the DataSource for the BindingSource, then bind the controls to the BindingSource.
The BindingSource class has SuspendBinding() and ResumeBinding() functions.

Resources