Yet another coding blog covering everything from C#, WPF, SQL, and Silverlight to any other random thought that passes my way…
RSS icon Home icon
  • Migrating posts from my old blog

    Posted on April 25th, 2009 biggert No comments

    My old blog (http://blog.attobase.com) which was going to be centered around some open source work I was doing is having some issues. I planned on migrating the information from that blog over to this one eventually but with the recent problems, I’ll be doing this sooner rather than later. I hope to get most of that done this week. The project (a stored procedure which creates a delimited text file from SQL) will definitely be brought over since it seems to get a good handful of traffic from Google searches and does help a few folks out on occasion. I also have some posts about using OPENROWSET which might be helpful to a few…

    Edit: Of course Dreamhost’s excellent support comes through and fixes it right up!

  • SQL Bulkcopying performance work

    Posted on April 22nd, 2009 biggert 1 comment

    Some of my time spent in application performance tuning around out SQL backend products is reviewing code that could otherwise be performed on the SQL server with much faster results. Over the years, I’ve spent a lot of time with .NET’s SQLBulkCopy and SQLXML BulkLoad. I’ve spent countless hours scheming up new ways to get our data processing techniques out of  un-scalable C# code of row by row (or chunks) processing of the data and into the blazing fast world that is SQL BulkCopy/BulkLoad.

    One recent opportunity arose where we literally had a piece of C# code iterating row after row, performing some crazy logic, and then copying data from one table to another, and throwing around some more logic and performed updates back on the 2 tables. To be a little more specific, we had a table full of filenames in a certain format and we needed to copy this data into a separate table with more metadata about the filenames. We then wanted to copy some data from this table to yet another table. Very generic statements I know but this isn’t exactly an open source product.

    This code block took over 3 hours to run for a measly 10,000 rows. We applied a few BulkCopies and were very happy with the results. We actually added code to dynamically create a working table (I want to avoid the word “temp table” since it is not a true SQL temp table but in the scope of the application, since it is added and removed, it is a “temp table”). With this working table, we could then convert the C# Logic to logic performed in a SELECT statement which also prevents UPDATE statements from being executed so that this can be an INSERT only (much faster in the SQL world). So finally, we converted a couple hundred lines of C# code to 3 BulkCopies (1 for the working table, 2 for our tables). All the logic is performed in 3 SELECT statements optimized to their fullest (dirty reads where possible, LEFT JOINs instead of IN/NOT IN, limited subqueries, etc.).

    Overall, in the grand scheme of things, to be fair, the complete process of some of which is not mentioned here took about a thousand lines of code which took over 3 hours to run for 10,000 rows to 5 bulkcopies using 3 working tables and the result is over 100,000 rows takes 3 seconds. Three seconds… to be fair with a direct comparison, the original 10,000 rows takes 2 seconds, most of which is spent creating the “temporary working tables” or opening the SQL connection/SQL DataReaders. Awesome stuff!

  • Mystery WPF problem that I need help with…

    Posted on April 20th, 2009 biggert 1 comment

    I didn’t want to do this so early in the life of this site but I’m at a loss of what to do. We’ve got a heavy WPF application which has a nice little animated progress spinner on it using WPF animation (DoubleAnimation). The problem is basically laid out here: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a4b2df90-8fa3-4b59-9242-9c48000fa62a. As you can see, there’s no answers yet and it’s been out there since March. We are seeing this randomly occur in our application and I have identified the source POSSIBLY being the progress spinner’s infinite animation (we turned the animation off and don’t see the problem again… yet).

    Here’s our stacktrace. As you can see there, is not specific source to OUR code… it’s all WPF internals… and this happens completely randomly at random intervals and is not reproduceable on some machines. I appreciate any help that can be provided.

    ===================================

    Unhandled exception detected in application. Please see technical details for more information: UIElement.Measure(availableSize) cannot be called with NaN size.

    ===================================

    UIElement.Measure(availableSize) cannot be called with NaN size. (PresentationCore)

    ——————————

    Program Location:

    at System.Windows.UIElement.Measure(Size availableSize)

    at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)

    at System.Windows.Controls.ItemsPresenter.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)

    at System.Windows.Controls.ScrollContentPresenter.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)

    at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV)

    at System.Windows.Controls.Grid.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.ScrollViewer.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.Border.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.Control.MeasureOverride(Size constraint)

    at Microsoft.Windows.Controls.DataGrid.MeasureOverride(Size availableSize)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.DockPanel.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)

    at System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)

    at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV)

    at System.Windows.Controls.Grid.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.Control.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)

    at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV)

    at System.Windows.Controls.Grid.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)

    at System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)

    at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV)

    at System.Windows.Controls.Grid.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.Control.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.DockPanel.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)

    at System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.Border.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.Controls.Page.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)

    at System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint)

    at System.Windows.FrameworkElement.MeasureCore(Size availableSize)

    at System.Windows.UIElement.Measure(Size availableSize)

    at System.Windows.ContextLayoutManager.UpdateLayout()

    at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)

    at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()

    at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()

    at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)

    at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)

    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)

    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

    EDIT: Grrr.. even with the animations off, there’s still a problem. Here’s a new stacktrace:
    ===================================

    Unhandled exception detected in application. Please see technical details for more information: TimeSpan does not accept floating point Not-a-Number values.

    ===================================

    TimeSpan does not accept floating point Not-a-Number values. (mscorlib)

    ——————————
    Program Location:

    at System.TimeSpan.Interval(Double value, Int32 scale)
    at System.Windows.Media.MediaContext.ScheduleNextRenderOp(TimeSpan minimumDelay)
    at System.Windows.Media.MediaContext.EstimatedNextVSyncTimeExpired(Object sender, EventArgs e)
    at System.Windows.Threading.DispatcherTimer.FireTick(Object unused)
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

    EDIT: Just wanted to update everyone on how we minimized this issue. From the MSDN forums, the only common link we could find is our development machine hardware/software. The only conclusion we could come up with is a WPF incompatibility between our hardware and/or software. We added an app settings flag that is checked before any infinite animations are executed and that flag is set to true to disable the animations on our development machines but set to false during deployment. This gives us access to enable/disable this feature if we ever see it occur on client computers (which we hope does not happen!).

  • Quick way to lower CPU usage in heavy WPF animation desktop app

    Posted on April 17th, 2009 biggert 1 comment

    Earlier this week, we ran into an issue where our desktop application (WPF heavy) was attacking our CPU cycles. Upon further investigation, all problems pointed to our lovely progress spinning controls which are powered by looping WPF animations. After some dabbling with replacing the animations with animated GIFs turned out to be more than its worth (and still gobbled a few cycles), we decided to go with a lovely suggestion from the MSDN forums about reducing the frames per second on the WPF animations update.

    The result was this simple little piece of code:

                    Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline), new FrameworkPropertyMetadata { DefaultValue = 20 });
    

    A small reduction in the visual refresh rate down to 20 FPS (not easily noticeable to the user) resulted in a huge decrease in CPU usage… from over an average of 30% CPU usage down to an average of 5%.

    On a separate note… word to the wise, don’t bind properties directly to UI elements in WPF which internally make database calls… even if you load the items asynchronously, WPF will bind and make the DB calls on the main thread which will block the UI.

  • Virtualized WPF Listbox scrolling (because ScrollIntoView doesn’t always work)

    Posted on April 16th, 2009 biggert 3 comments

    I guess I’ll start this off the fun way… with a recent issue I was involved with yesterday regarding a rogue list box. So to explain the issue, I’ve got a virtualized list box full of nice little custom objects. The user has access to delete these items from said listbox. The problem comes into play where, if the user has scrolled down the listbox but then deletes the items they are looking at and the scroll bar disappears (it will disappear if the number of items in the listbox is less than the amount that needs a scrollbar), the user can no longer scroll to the top of the listbox. So the items will be inaccessible!

    After spending a little time Googling and realizing that ListBox’s ScrollIntoView did nothing, I found an excellent forum post that detailed the notion of directly accessing the scrollviewer inside the listbox Once I had access to that, I could scroll all I wanted to.

    I basically just added this function:

            private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                    if (child != null && child is childItem)
                    {
                        return (childItem)child;
                    }
                    else
                    {
                        childItem childOfChild = FindVisualChild<childItem>(child);
                        if (childOfChild != null)
                        {
                            return childOfChild;
                        }
                    }
                }
                return null;
            }
    

    Adding a call to it to walk the visual tree for the scrollviewer:

    ScrollViewer sv = FindVisualChild<ScrollViewer>(uxListBox);
    

    And that’s it! Now I can sv.ScrollToTop(), ScrollToBottom(), or even specific vertical/horizontal offsets. I do have to make a call to ListBox.UpdateLayout() to refresh but it’s all good now… crisis #93487 averted!

    Thanks to this post for guiding me to the light!

  • 65 million seconds in the making…

    Posted on April 15th, 2009 biggert No comments

    And so it begins, yet another venture into the blogging world… this time without a specific topic (which hopefully will make it more useful for me). Over the next week or so, I’ll continue building the site but I thought I’d go ahead and release it to the world since the basic content is there.