When a 'z' just doesn't cut it... (Oren Nachman's random notes from Microsoft)

  • Randomisation

    Silverlight for Windows Phone 7 Performance Session at PDC!



    It's that time of year again - PDC 2010 kicks of tomorrow! Join the Silverlight Performance Team as we take you through the high level analysis of common performance issues that apps commonly run into. I'll be giving a live session titled "Optimizing Performance for Silverlight WP7 Apps" at 3:15pm (PDT)  on day 1 (28 October 2010).

    Even if you couldn't make it here to heckle me in person, the rest of the team will be online and answering your questions (or heckling on your behalf) as you watch the live stream via the online player, which you'll be able to find at http://player.microsoftpdc.com 

    Make sure to check out the session before mine ("Things I Wish I Knew about Building WP7 Apps" by Jaime Rodriguez) and all of the rest of the Windows Phone 7 track. There's other great content at PDC that's worth checking out, but we all know that that's secondary!

    See you there!


  • Randomisation

    Silverlight: Why do I get 0x8000ffff when using WriteableBitmap on an Element


    I'm working on a WP7 library which helps analyze your VisualTree and to provide a visual aid, I take WriteableBitmap snaps of the elements. Unfortunately I (seemingly) randomly encounter the following exception:


    A first chance exception of type 'System.Exception' occurred in System.Windows.dll
    When digging into the exception you may find that the error is actually a HRESULT which is being bubbled up from the lower native layer:


    E_UNEXPECTED (0x8000ffff) 

    What's going on?

    You guessed it - this isn't random! In fact, this only happens on completely obscured (or off screen) elements which have never had a chance to render. In this case when you try to take a WriteableBitmap snap, instead of it forcing the control to render, it simply fails. This will hit you in the case of any element that has always been obscured. As soon as the element is unobscured it will be good to go (so you could do some VisualTree manipulation if you *really* needed to grab that shot).


  • Randomisation

    WP7 Marketplace Tip #1: Submit one app with multiple locales


    ... as opposed to multiple apps, each with a different locale.


    1. If these are free apps, then each language will count towards your free app quota (you get 5 free apps that you don't need to pay certification costs for)
    2. Regardless of price, each app will need to go through independent certification (which will then take longer for all apps to be released), instead of one app being certified and published with all languages

    Happy App Hubbing!

  • Randomisation

    Are the Windows Phone 7 Developer Tools Still Free?


    YES! Visit: http://create.msdn.com/en-us/home/getting_started and click "Install Now" to download the tools, directly, for free, without the need to sign up first.

    Ever since the release of the new developer portal (http://create.msdn.com) I've been hearing that you need to signup to get the tools, hence they must no longer be free. In reality, what happened is that the old developer website url redirects directly to a login screen, instead of to the new site, leading people to believe that the tools are no longer free. Let me assure you - they are :)

    Happy App Hubbing!

  • Randomisation

    WP7 Perf Tip #6: Be smart about graphics (use JPEG where possible)


    Take Away's:

    1. Wherever possible (i.e. no transparency) use JPEG images since these decode faster than PNG
    2. Make sure your images are correctly sized (you don't want to waste cycles with resizing on the fly)
    3. Always compile your images with a "Build Action" of "Content" instead of the default "Resource"

    Some Background:

    1. JPEG (JPG) decodes faster, simple as that. The difference will continue to shrink over time, but every cycle is important on the phone, especially on image intensive applications.

      Don't take this to mean "never use PNG", rather, PNG is slower so only use it when you need it (transparency) as opposed to for everything as a generic default. 
    2. Although resizing is quick (even if it looks ugly) there is no point wasting those cycles resizing images on the fly (Silverlight will do this for you) if you can already size the images correctly from the start
    3. The default when adding new images is to set "Build Action" to "Resource" (under the Properties window). Make sure to always change this to "Content" in order to reduce the size of your DLL, speeding up both app load and image load.

      The properties window, with the correct "Build Action" set


  • Randomisation

    WP7 Perf Tip #5: Check your memory usage


    Two for the price of one today!

    Take Aways:

    1. Make sure your memory usage is below 90MB.
    2. Always check your memory usage while you're developing your app (preferably on device) by using the following code:
    long deviceTotalMemory = (long)DeviceExtendedProperties.GetValue("DeviceTotalMemory");
    long applicationCurrentMemoryUsage = (long)DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage");
    long applicationPeakMemoryUsage = (long)DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage");


    The Windows Phone 7 Application Certification Requirements specify (as of 28th of September 2010):

    5.2.5 Memory Consumption

    The application must not exceed 90 MB of RAM usage. However, on devices that have more than 256 MB of memory, an application can exceed 90 MB of RAM usage. The DeviceExtendedProperties class can be used to query the amount of memory on the device and modify the application behavior at runtime to take advantage of additional memory. For more information, see the DeviceExtendedProperties class in MSDN.

    Since you have a hard limit of 90MB (exceedable in some cases) it's worth checking that you're not getting anywhere near that while your app is running. The code above will give you the Peak (which is important to make sure you've never crossed the 90MB barrier) and the current memory. If you call that out every now and then you should be able to get a pretty good idea of how your memory fluctuates during the lifetime of the app.

    Can I Go Above 90MB?

    Sure - but be careful! If you're app is memory intensive and would benefit from a little extra breathing room, then feel free to add some extra logic which dynamically loads more items into memory until a certain limit is hit. Note though that there is no defined limit above the 90MB barrier, so expect this to be clarified in the future.


    Kudos go to Stefan Wick, Principal Test Manager for pushing this code

  • Randomisation

    WP7 Perf Tip #4: Use fully qualified paths when setting the source property


    File this one under "Sad, but True"...

    Take Away's:

    Always prefix your source paths with a "/" (full-qualified path) instead of simply using relative paths.


     <Image Source="/Resources/Images/Background.jpg"> 


     <Image Source="Resources/Images/Background.jpg"> 

    But they both work!?!

    True, both of these will work, equally well (visually), but performance wise the relative path will do extra lookups which waste time, and can hit the SD card more than you want it to (causing further slow downs). This is something that we will fix on our side in the future - since all storage is isolated and we can assume that there is always a "/" (if there is no ".."). For now, it doesn't hurt to get the extra performance boost by simply prefixing your paths with a "/".


    As Luke Kim, a friend from Microsoft, pointed out "/" paths are not really full qualified paths. To make things clear though, I use the term "full qualified" since we are within the confines of the .NET IsolatedStorage framework and there is no access to the rest of the system, "/" paths are as fully qualified as you get (without actual URI specifiers). Thanks for pointing this out!

  • Randomisation

    WP7 Perf Tip #3: Read the performance document


    This is kind of obvious - but important. Read the White Paper which was written by the Silverlight performance team (mainly Shane Guillet) and browse through the samples that come with it. In these blog posts I'll try to distill specific items from the paper into blog format, but you can't replace the feel of the complete paper.

    Additionally check out the performance video with Shane, which runs through a lot of the samples from the document and distills specific tips and tricks to get your app running smoothly: http://channel9.msdn.com/shows/Inside+Windows+Phone/Inside-Windows-Phone-03-Optimizing-Windows-Phone-Silverlight-applications/

  • Randomisation

    WP7 Perf Tip #2: Know your ProgressBar


    Take Away's:

    1. Do not use the built in ProgressBar straight up, use Jeff's template 
    2. When you're done with an indeterminate ProgressBar, make sure to toggle IsIndeterminate to False and Collapse the bar
    3. General: Always make sure to stop animations / remove animating controls when they're no longer needed 

    Some Background:

    Due to a bunch of different reasons the shipping ProgressBar control is suboptimal and will actually be UI thread bound - meaning that if your UI thread is stuck working, your ProgressBar will be stuck as well. Not a great situation for a ProgressBar, huh?

    That said, we're not leaving you high and dry. Jeff Wilcox has a great solution which changes the template for the ProgressBar to only run on the Render thread - meaning that it will continue ticking, even when you're doing your heavy loading work on the UI thread. That said, it still comes with a gotcha - don't forget to set IsIndeterminate to False and to Collapse the bar once your done (instead of just setting Visibility to Hidden) so that the ProgressBar doesn't continue to tick in the background, eating up Render thread cycles.

    As a general rule, highlighted especially by the ProgressBar, you should always make sure to stop animations (not pause) and remove / collapse animating controls when they're no longer needed.

    Remember: just because you can't see a animation / control doesn't mean that it isn't there doing work.

  • Randomisation

    WP7 Perf Tip #1: Test on Device


    I'm kicking off a series of posts about Silverlight perfofmance under Windows Phone 7 with a a kind of obvious one, but one that is important to keep in mind from the get go.


    • Test your code on device as much as possible 

    But the Emulator is awesome?!?

    True, the emulator, otherwise known as the x86 Device Emulator, or simply XDE, is awesome, but it is still not an accurate representation of a device. In fact since the XDE is usually so smooth, it's extremely easy to fall into the trap of adding more features "because it works on the emulator".

    The Hardware

    The emulator restricts itself to one core, adds artificial Sleep()'s and limits the amount of memory it is happy to eat up (so it won't just chew through whatever is available), but that still isn't enough.Chances are that even running at one core the emulator is still running faster than the device (most cores today are going to be running faster than 1GHz and chances are you are going to have less things running on that core than the device does). Throw in a desktop GPU which beat a mobile GPU handsdown and you've got a winning combination. If you happen to have an older machine, then the XDE will simply run like a dog - and you won't be able to tell if your app crawls because of your code or because of your machine.

    But I don't have a device!

    Common problem, especially in these trying, pre-release, times. Fear not though! Your local Microsoft office most likely has some devices and can help hook you up. Shoot them an email and let them know that you are working on an app, include a description and some screenshots from the XDE (to sweeten the deal) and they should be able to help.

  • Randomisation

    WP7 Silverlight TextBoxes No Longer Scroll


    There's a change in the pipeline that will be hitting the public Windows Phone 7 images at some point soon (post the current Beta), which removes the ScrollViewer from a TextBox's template.

    What does this mean?
    Basically, long TextBoxes will no longer scroll when you gesture over them - the gesture is ignored and there is no visual reaction. Tapping remains the same (the keyboard pops up) as does tapping and holding (the enlarged caret is shown, and you can use this to, sort of, scroll).
    How do I work around this?
    Most scenarios do not require scrollable TextBoxes, but if your's does you can either place the TextBox inside a ScrollViewer (though this can cause some texture issues), or preferably re-add the ScrollViewer into your TextBoxes template, so that it still scrolls as usual.


  • Randomisation

    BUG: Silverlight Crashes (Along With the Browser) When Profiled


    It's one of those bugs... If you've tried profiling Silverlight lately and you've run into a consistent crash in Silverlight which brings down the browser, but only on specific projects then this bug is for you.

    Basically, profiling any Silverlight app (plugin or OOB) that takes advantage of Shaders will cause Silverlight (and its container) to crash. The only current workaround is to remove the shaders before profiling (possibly with an #ifdef if you are so inclined). This is slated to be fixed in an upcoming version of SL 4 (though no release dates yet).

    Note: people often get scared of crashes since they can indicate a security bug - but this is not a security issue (the profiler puts us into a bad state, causing the crash). 

  • Randomisation

    Debugging Silverlight in Firefox 3.6.4 (and newer)


    While they chug along to Firefox 4, Mozilla just released Firefox 3.6.4 (and quickly followed up with 3.6.6) on the world, sporting a new feature - plugin isolation. By isolating plugins to a different process, Firefox catches up to Chrome in stability, by ensuring that a rogue plugin that crashes does not bring down the whole browser, instead you get the sad face informing you that something has happened. This is a great end-user feature which will increase the general reliability of a user's browsing experience - but we aren't just users, are we?

    Firefox will shut down a plugin when it is deemed to be either dead, or frozen. Unfortunately frozen is the state that the plugin will enter when you try to debug it (say, through Visual Studio), causing Firefox to kill the plugin and continue on its merry way. There have a been a number of proposed solutions, mainly around disabling the plugin container for Silverlight (see this forum post). Unfortunately, while this works for debugging, this is not a real user situation that you are debugging (since you're no longer locked in the container, which is the expected state for any user running your app). In order to get Firefox to still run Silverlight in the container, but not kill it when it detects a Freeze, do the following:

    1. type about:config
    2. find dom.ipc.plugins.timeoutSecs (you can start typing it in the filter)
    3. change the value to -1

    This effectively cancels the timeout so that even though the plugin is no longer responding to Firefox's NSAPI messages, it will not be killed.

    Happy bug hunting!

  • Randomisation

    Windows Phone System Tray obscures FrameRate counters


    Here's a small tip for those of you who want to debug performance in a Windows Phone Silverlight app with the frame rate counters, but have the System Tray visible - hide it.

    The counters currently show up behind the system tray (since technically the tray is a system overlay which is drawing over the surface available to your Silverlight app), so hiding the tray will show the counters.

    Don't forget: to re-enable the system tray when you're done!

  • Randomisation

    Profile Silverlight 4 from the VS 2010 UI (Premium & Ultimate only)


    Maxim has a great post detailing a workaround which allows you to get some profiling functionality from the Visual Studio 2010 UI, without restoring to the fun that is the command line profiler interface.

    Check it out.

  • Randomisation

    Profiling Silverlight 4 with Visual Studio 2010


    Silverlight is now into its fourth version (woo!) and with each iteration the platform becomes more solid, more mature and easier to develop for. One of the newer features that is now supported "out of the box" with Silverlight 4 is the ability to profile your Silverlight application, but you wouldn't know it from just digging around the menus of Visual Studio. In this post we'll explore the process of collecting a profile from your XAP (both in and out of browser) and we'll touch on common troubleshooting techniques for failed profiles.

    What You'll Need

    1. Visual Studio 2010 Ultimate or Premium (check out the product comparison, under "debugging", to see if your version has profiling support)
    2. Silverlight 4 for Developers (includes the tools for Visual Studio)
      Note: you can't profile the normal version of the Silverlight plugin (there's a bit of registry and file magic that will be missing)

    Ready, Set, Profile!

    Here's the quick and easy way to profile - open an elevated Visual Studio 2010 Command Prompt (pre configured with useful Visual Studio commands) and run the following:

    VSPerfClrEnv /sampleon
    VSPerfCmd -start:sample -output:somefile.vsp
    VSPerfCmd -globalon
    VSPerfCmd -launch:"c:\Program Files (x86)\Internet Explorer\iexplore.exe" -args:""
    VSPerfCmd -shutdown
    VSPerfClrEnv /off

    This will create a VSP (Visual Studio Profile) file in the current directory, which you can then open in Visual Studio.

    Note: If you plan on profiling Internet Explorer 8 (and up) you must disable its per-tab process feature (otherwise you'll end up profiling the iexplore container process instead of the process that is hosting Silverlight). You can find more information here.

    Tips & Tricks / FAQ (Recommended Reading)
    Take a couple of minutes and run through the following, since you are most likely going to run into one of these issues on your first go...

    • Can I Profile Silverlight 3 Projects?
      You can only profile a Silverlight 3 project if it is running under the Silverlight 4 plugin. There are moves to release the supporting files to allow profiling of Silverlight 3, but now that Silverlight 4 is out the point is perhaps moot.
    • Associate VSP Files with Visual Studio
      This one makes it easy to open VSP files directly from the command prompt (and aides in symbol resolution) - try to open a VSP from Explorer and when it asks you which program to use, select devenv.exe
    • Symbols Fail to Resolve when opening VSP
      If the missing symbols are in Microsoft DLLs, make sure you have selected the public symbol server in your debugging options in Visual Studio under Tools->Options->Debugging->Symbols.

      If the missing symbols are in your own DLLs (like from your own XAP) then make sure to either launch the VSP from the directory that has your PDB files (see the above suggestion regarding associating VSP files with Visual Studio), or add the directories with your PDB files to your symbol path by adding them under the same tool window as above.

    • Can I Start Profiling After Launching my Target?
      Sure - you just need to change the order a bit:
      VSPerfClrEnv /sampleon
      VSPerfCmd -start:sample -output:somefile.vsp
      VSPerfCmd -launch:"c:\Program Files (x86)\Internet Explorer\iexplore.exe" -args:""
      VSPerfCmd -globalon
      VSPerfCmd -shutdown
      VSPerfClrEnv /off
    • Can I Stop Profiling Without Closing the Target?
      You bet!
      VSPerfClrEnv /sampleon
      VSPerfCmd -start:sample -output:somefile.vsp
      VSPerfCmd -globalon
      VSPerfCmd -launch:"c:\Program Files (x86)\Internet Explorer\iexplore.exe" -args:""
      VSPferfCmd -detach
      VSPerfClrEnv /off
    • My profile doesn't have any of my functions!
      This is probably the most common problem and there are a couple of things to check:
      1. With the VSP open pull up the "Modules" view - if there are some GUIDs in the list of modules, then your code was picked up, but Visual Studio couldn't find your symbols - continue to the next step
      2. Pull up the Output window (usually Alt+2, View->Output) and you'll see a list of symbols that were loaded:

        Loaded symbols for C:\Windows\SYSTEM32\ntdll.dll.
        Loaded symbols for c:\Program Files\Microsoft Silverlight\4.0.50401.0\npctrl.dll.
        Loaded symbols for c:\Program Files\Microsoft Silverlight\4.0.50401.0\agcore.dll.
        Loaded symbols for C:\Windows\system32\WINMM.dll.

        You may also see one of the two following possible warnings:

        Failed to load symbols for C:\Windows\System32\nlaapi.dll.

        The most common problem - Visual Studio has found the DLL that it profiled, but it can't find the symbols for it. You'll need to adjust your symbol path to find the PDB files for your project and then reload the VSP.

        Warning VSP2701: Kit3D.dll could not be found when looking for symbol information.

        This is what you'll see if you're profiling a XAP from the internet - Visual Studio can't find the DLL that it profiled (because it was in the XAP that was downloaded) and thus can't load it to find corresponding PDBs. Load the VSP from the directory that has your DLLs in them (or add that to your global PATH), or download the XAP and extract the DLLs and this warning will go away. Note that if you don't have the PDBs then the warning will just morph into the above "Failed to load symbols".

      3. Your DLLs are not in the list: Make sure that you launch the command to profile from the Visual Studio Command Prompt. Failure to do so will result in a bunch of native DLLs being profiled, but no managed code.
      4. Your code isn't doing enough work: Although a little less likely for heavy apps, some simple apps simply don't do enough work. The profiler is sample based, meaning that it will take a snapshot (sample) of the call stack every so often. If the time spent in your code is extremely little, due to your code being so fast, it is likely that the profiler will simply miss your code. You can increase the amount of collected samples, to increase the likelihood of hitting your code by running something like:

        VSPerfCmd -timer:5000000

        This controls how often we sample by specifying the number of cycles before sampling (default is 10,000,000). You can also play around with -pf (sample of every n page faults) and -sys (sample on every n system calls). See -? for more info...

    • Can I attach to a Running Process?
      Yes & No. You can attach to any process that was started within an environment that had the profiling variables set (so for example, any program you launch from a command prompt after running "VSPerfClrEnv /sampleon"). If you attach to a process that wasn't started within the correct environment you will only get native call stacks and no managed code. To attach to a PID use:

      VSPerfCmd -attach:PID
    • Which Modules are Silverlight Itself?
      Silverlight is made up mainly of native code which can be found in two DLLs, agcore.dll and npctrl.dll. Can you guess why the ag?
    • Why isn't Silverlight support baked into the IDE?
      Stay tuned (both for a stopgap and a final solution).
    • When will we see debug symbols MS?
      This was a question on Maxim's blog - I'm not sure what the poster was actually getting at though. Microsoft publishes symbols for all released versions of Silverlight (and some select pre-release versions). These symbols are always the retail symbols - there are no CHK builds (or similar) for Silverlight with extended symbols. All of the information that you would want should be in the public symbols - I would love to hear about something that is missing...
    • I Want More Options!
      This is an important one - check out:

      VSPerfCmd -?

      For a wide range of options, a lot of which I haven't touched on here.

    26/4/2010 Edit: Maxim has a great post which walks you through profiling an actual app using similar steps to those described here - worth checking out!
    28/4/2010 Edit: Updated FAQ with some questions from Maxim's blog
    29/4/2010 Edit: Added note about IE8

    Originally published here.

Page 2 of 2 (41 items) 12