Randomisation

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

Posts
  • Randomisation

    WP7 Silverlight Perf Demo 1: VirtualizingStackPanel vs. StackPanel as a ListBox ItemsPanel

    • 2 Comments

    This is the first in a series of blog posts which run through the demos from my PDC 2010 talk, with small updates and full code download.

    The Demo

    Download the sample

    Load the xap and then compare the two scenarios on the main page. Look out for:

    1. The smoothness (if at all) of the animation in the center of the page (before the listbox shows)
    2. The amount of time it takes to load the listbox
    3. Once the listbox is up, try flicking through it as quickly as possible. See which list creates blank items during flick and which one scrolls smoother.

    Takeaway

    Startup Memory Scroll
    VSP Fast (instantiates 3 screens worth of list items) Less (3 screens worth of UI elements) May have slight jerks / blank items if your templates are heavy and your items can’t be brought in fast enough.
    SP Slow (instantiates all items from the get go) More (all elements are loaded at once) Smooth (once loaded)

     

    1. The default ListBox template is VirtualizingStackPanel (VSP). This can be overridden to use a normal StackPanel (SP), or any other container, by using code similar to the following:

      <ListBox.ItemsPanel>
      <ItemsPanelTemplate>
      <StackPanel>
      </StackPanel>
      </ItemsPanelTemplate>
      </ListBox.ItemsPanel>
       
    2. VSP will load faster (since it only loads 3 screens worth of items) and use less memory (see: WP7 Perf Tip #_:  Understanding UI Virtualization) but may have more blank items during scroll, especially if your DataTemplate is complex and takes too long to be instantiated for each new item coming in. 
    3. SP will load much slower (since each item is created ahead of time) and use a lot more memory (relative to the number of items) but once loaded will be smoother since there is no extra work that is needed to be done as you scroll through the list.

    When Should I Use One Over the Other?

    The VSP is the desired Panel for most cases, though for small lists (1 – 200 items) that don’t take up to much memory (don’t forget to measure!) you may find that If you can handle the startup cost, the list will handle a lot better (especially for complex DataTemplates).

     

  • Randomisation

    WP7 Perf Tip #5: Check your memory usage

    • 2 Comments

    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");

    Why?

    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

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

  • Randomisation

    Getting Started with Node.js and Mango

    • 0 Comments

    It's been a while since I've found time to blog - but it's not like I've left you in cold hands. Rohan has been doing a great job posting on the Silverlight for Windows Phone Performance blog (check it out if you haven't yet).

    On a completely non-performance related topic (we'll get to those in the next couple of blog posts), I've been meaning to play around with Node.js for a while, and when a colleague posed a question about using it with Mango, I thought it might be a great excuse to polish off the Beta 2 tools (get them while they're hot!) and do some Socketing!

    First things first - grab 7zip (if you don't have it already), and Node.js binaries for Windows (or build it yourself). Extract these to a convenient location and you should be good to go.

    We're going to use the Hello World sample ripped straight from the Node.js homepage, with one extra debugging addition (highlighted in yellow) and a practical change (highlighted in green - see "gotcha!" below):

    var http = require('http');
    http.createServer(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end('Hello World\n');
     console.log('Sent message'); }).listen(1337, "192.168.2.125");
    console.log('Server running at http://192.168.2.125:1337/');

    Gotcha Warning!

    A common mistake at this point is to stick with the sample's use of 127.0.0.1 (locahost). This will work great from your browser, but not from the emulator or your device (regardless of whether it is connected to WiFi or tethered via Zune). This is because the emulator and the device join the network as *new* devices which means they get a newly assigned IP address and they act just as though they were a machine on the network. This leads to 127.0.0.1 pointing back to themselves, which is not allowed, leaving you with a "NetworkDown" network error. Instead, make sure to set your IP to your local LAN address (usually starts with 192.168.X.X or 10.X.X.X). You can find your exact IP address from cmd by typing "ipconfig" and looking for the address that corresponds to your local network.

    Testing the Server

    Now, save your modified script somewhere somewhere convenient (I saved it to c:\nodejs\bin\servers\helloworld.js) and then launch the server with a simple:

    C:\nodejs\bin>node servers/helloworld.js
    Server running at http://192.168.2.125:1337/

    Note the use of UNIX style paths... If you see any errors at this point it's most likely path related. Fix your path so it is relative to your binary and you should be good to go. Need to verify that everything is working? Fire up your browser and enter http://localhost:1337 and you should see "Hello World!".

    Note: When launching the server you may get the Windows warning dialog about a program accessing the network, feel free to set the settings to whatever you are comfortable with, just note that Node.js will need at least local network access so that you can talk to it from the emulator / a device over WiFi.

    Let's get me some Windows Phone!


    We're up and running, so time to get our hands dirty with some C# code. Open Visual Studio and start a new C# Windows Phone application targetting "Windows Phone 7l.1" (which is the code target name for Mango). The project that we create is going to do something extremely simple - it's going to open the socket, send a request for data (it's really a dummy request since this server isn't really waiting for a real request) and then displays the response, verbatim, on the screen.

    Once you have the project created add a button (btnStart), which will kick the whole process off, and a textblock (txtServerResponse) to contain the server response. We're not going to use binding to simplify the sample, but you can certainly do that instead. Add a Click handler to the button by double clicking on it and add the following code to MainPage.xaml.cs. The code is heavily documented so should answer any further questions you might have. I've also stuck a zipped version of the project (including the mini-server) which you can use to experiment with.

            
    private Socket _socket;
    
    private void btnStart_Click(object sender, RoutedEventArgs e)
    {
        // the message to send to the server
        byte[] message = UTF8Encoding.UTF8.GetBytes("GET / HTTP/1.1\nHost: localhost\n\n");
    
        // the address we'll be connecting to
        IPAddress address  = new IPAddress(new byte[] {192, 168, 2, 125});
        
        // an endpoint translates into the complete destination - address + port
        // you can also use a DnsEndpoint to look up an IP address from a hostname
        IPEndPoint endpoint = new IPEndPoint(address, 1337);
    
        // all socket operations are asynchronous on the phone so you must set up 
        // a SocketAsyncEventArgs object to let the socket know how to act
        SocketAsyncEventArgs args = new SocketAsyncEventArgs() { RemoteEndPoint = endpoint };
        
        // don't allow multiple clicks before the request finishes
        btnStart.IsEnabled = false;
    
        // create our socket, note that it isn't connected yet
        _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
        // set up the call back to be called when we finish connecting to the socket
        args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSocketConnected);
    
        // neat trick - setting the buffer of a socket before it connects will cause the socket to send
        // that data as soon as it connects
        args.SetBuffer(message, 0, message.Length);
    
    
        // boom! we're off
        _socket.ConnectAsync(args);
    }
    
    void OnSocketConnected(object sender, SocketAsyncEventArgs e)
    {
        if (e.SocketError != SocketError.Success)
        {
            // don't forget that we're now on a background thread so anything that interacts with
            // the UI thread (MessageBoxes, updating UI etc) has to be dispatched back
            Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show("(Connect) Socket error! " + e.SocketError.ToString());
            });
            return;
        }
    
        // we're done with the connect + send, time to receive
    
        // create a buffer for the respone
        byte[] buffer = new byte[1024];
    
        // create the Socket event args for this receive
        SocketAsyncEventArgs args = new SocketAsyncEventArgs();
    
        // set a buffer for the receive - the size will be the maximum amount read
        args.SetBuffer(buffer, 0, 1024);
    
        // we have to come back somewhere after the receive completed
        args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSocketReceive);
    
        // kick off the actual receive
        _socket.ReceiveAsync(args);
    }
    
    void OnSocketReceive(object sender, SocketAsyncEventArgs e)
    {
        if (e.SocketError != SocketError.Success)
        {
            Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show("(Receive) Socket error! " + e.SocketError.ToString());
            });
    
            return;
        }
        
        // the response comes back as a byte array, so convert it to a string
        // Note: usually you would read from the buffer and then call _socket.ReceiveAsync(e)
        // again until e.BytesTransferred == 0 (signals end of the receive), for this example
        // we're going to keep it simple
        string response = UTF8Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred - 1);
    
        // we have our response now update the UI thread
        Dispatcher.BeginInvoke(() =>
        {
            txtServerResponse.Text = response;
            btnStart.IsEnabled     = true;
        });
    }
    

    What does it look like?

    Questions?

    Feel free to leave comments below - Good Luck!

  • Randomisation

    WP7 Silverlight Gotcha: Using the ListPicker from the Toolkit may cause you to fail certification

    • 0 Comments

    Applies To: Anyone using the current iteration of the Silverlight Tookit from Nov 2010

    Toolkit Link: http://silverlight.codeplex.com/releases

    Quick Bits

    A Toolkit ListPicker control that has less than 5 items in it will display inline (expands) but will not collapse when you press the back button (like the native control does). This can cause you to fail certification due to an erroneous interpretation of the certification guide.

    The Fine Print

    According to section 5.2.4c the following applies to the use of the Back Button:

    If the current page displays a context menu or a dialog, the pressing of the Back button must close the menu or dialog and cancel the backward navigation to the previous page. 

    The Setup

    You have a ListPicker with less than 5 items in it, using the standard Silverlight Toolkit library.

    The Sting

    The Toolkit ListPicker doesn't listen for the back button when the ListPicker is in mini mode (i.e. it doesn't pop up the full screen list picker), so when you press back normal navigation occurs.

    The Solution

    There will be an update to the Toolkit coming out sometime this month that will address the issue, but if you want a fix now you basically need to either fix the Toolkit or listen in on the navigation event (and then check if a ListPicker is expanded and if so collapse it). I prefer the first option, since it's easy and you don't need to write redundant code if you have heaps of ListPickers.

    To this end, you can download a patched ListPicker.cs file (replace this within your Toolkit Source project), or a built Toolkit DLL (unzip and replace your Toolkit installation under C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.0\Toolkit\Nov10\Bin), with one change - the ListPicker will now respect the back button.

    Does It Really Matter for Certification?

    Actually, no. My reading of the certification guide doesn't indicate in any way that this is the expected behaviour, not to mention that I (and a bunch of other people) have other apps that were approved with the same control!

    So, I fought the good fight, and lodged a support request (complaint) and got the following response:

    Dear Oren,

    I am sorry for the inconveniences you experienced!  It seems that there was a little misunderstanding during certification testing.  Dropdown list or list control does not need to be collapsed at Back button press and instead its previous screen can come up or if the back button was pressed from the application's first page, it can exit the application.   Please add a short tester note while submitting it explaining that the list control is not dialog and does not need to be closed.

    We will also instruct our test team to correctly apply different expectations for list controls.

    Thanks,

    Windows Phone Marketplace Certification

    I was impressed (I don't think they even knew I was from within Microsoft)!

     

  • Randomisation

    WP7 Dev Tip: Detecting whether or not the user is playing music in the background

    • 2 Comments

    Applies To: Silverlight & XNA

    Quick Bits

    Microsoft.Xna.Framework.Media.MediaPlayer.GameHasControl

    The Setup

    Your app does some sort of music playing that doesn't make sense to blend into any already playing background music (for example, you're going to stream your own music) or you simply want to show a video.

    Why You Care?

    If you just start playing music you will fail certification according to section 6.5.1 of the certification guide if you don't ask the user if you can stop the background music, but how can you stop the background music if you don't know it's playing? Hence, you care!

    The Solution

    Query Microsoft.Xna.Framework.Media.MediaPlayer.GameHasControl (it's a bool) - if you have control, then you're good to go. If you don't have control, then there is something in the background and you need to prompt the user before continuing. 

    Silverlight Note: you'll need to link in Microsoft.Xna.Framework.dll for this to work, but make sure you don't distribute this file with your XAP by mistake (or you'll also fail certification for redistributing phone assemblies)

  • Randomisation

    WP7 Gotcha: Showing a Launcher or Chooser will crash while Navigating

    • 2 Comments

    Applies To: Silverlight & XNA (anyone using Launchers / Choosers)

    Quick Bits

    Always wrap [some launcher object].Show() with a try/catch block which catches InvalidOperationException, since running Show() while navigating (for example, if the user clicks your button multiple times quickly in succession) will cause this Exception to be thrown.

    The Setup

    You have a button that says "Purchase Me" which launches the Marketplace or one that says "Send Feedback" which launches Outlook to send an email. For example:

    EmailComposeTask emailComposeTask = new EmailComposeTask();
    emailComposeTask.To = "feedback@awesomeapps.contoso.com";
    emailComposeTask.Subject = "Feedback for AwesomeApp";
    emailComposeTask.Show();

    The Sting

    The user hits the button multiple times, quickly. The app crashes.

    The Cause

    If you debug this you'll find that you can't reproduce this behaviour on the Emulator (at least, I couldn't) but that it reproduces pretty consistently on the phone. 

    On the phone you'll get an InvalidOperationException with the following message:

    Navigation is not allowed when the task is not in the foreground. Error: -2147220989

    The Solution

    There are a couple of solutions - you could remember your state, so that if you clicked the button once and haven't navigated back yet then you just don't call Show(). Alternatively you could check if you were currently Navigating, and not call Show(). I personally prefer to wrap the statement in a try/catch block since it's the easiest to have to worry about and the cost for the try/catch block is minimal (performance wise).

     

  • Randomisation

    WP7 Marketplace Tip #3: Free app updates are free, even if they fail!

    • 12 Comments

    This has finally been clarified by the Marketplace team as the most current, up to date, lore on the subject of free app updates - they're free, they don't count towards your 5 free submissions, even if they fail. Here's the word for word story straight from a Marketplace PM:

     

    Paid Developer (USD$99):

    1.     Unlimited number of paid applications.   You cannot change the price on a paid app to be free.

    2.     Updates to paid apps that have been published are no charge.

    3.     5 submission credits for free apps

    4.     Updates to free apps that have been published are no charge.

     

    DreamSpark (free):

    1.     Unlimited number of paid applications.   You cannot change the price on a paid app to be free.

    2.     Updates to paid apps that have been published are no charge.

    3.     5 submission credits for free apps

    4.     Updates to free apps that have been published are no charge.

     

    * the failed updates for free apps are not  accounted against the developer quota

     

    What do I do if I get charged for an update to a free app?

    Submit a support request via the portal and you should get a response within 24 hours. Feel free to reference this blog post if needed.

  • Randomisation

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

    • 0 Comments

    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.

    Correct:

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


    Incorrect:

     <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 "/".

    Note:

    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

    WP Emulator Crashing on Windows 8? Here's a Fix

    • 3 Comments

    Don't you just hate it when you upgrade to a new OS (even when it's a beta) and everything works amazingly well, except for that one critical bit of infrastructure that just fails? That's kind of how you might be feeling if you boot up your brand spanking new Windows 8 install, install VS 2010 and the WP 7.1 SDK, followed by the 7.1.1. update to get the emulator and Tango support, boot up your project - hit F5... drum roll... emulator crashes. Sigh.

    Luckily, there's an easy fix!

    Rename all of the *.dess files under %systemdrive%\programdata\Microsoft\XDE and restart the emulator, and all should be good.

    What's going on? 

    For some reason the saved state of the emulator is getting corrupted, by renaming these files (which could probably be safely deleted) you're forcing the emulator to recreate them (shutdown may be a little slower the first time you close the emulator).

  • Randomisation

    Debugging Silverlight in Firefox 3.6.4 (and newer)

    • 0 Comments

    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 Power Tools 1.1

    • 2 Comments

    Grab them here

    I received a fair amount of feedback about the first version of the Power Tools mainly focused around the UI (people like modern today) and around "bug #1", which prevented files from uploading to the correct path in IsolatedStorage.

    I've just pushed a major UI rehaul to something somewhat more Metro-ish, loosely styled off Zune. It uses a combination of custom styles that you can find in the source tree and MahApps.Metro. I've also fixed the upload bug and other miscellaneous bits of polish here and there. This probably should have been a 2.0 or a 1.5 but it seemed to soon :)

    As always, feedback is welcome, though a reminder that this is not a Microsoft official tool.

  • Randomisation

    WP7 Silverlight Gotcha: Setting the Source on a MediaElement will stop background music playback

    • 1 Comments

    Applies To: Silverlight (the restriction applies to XNA, but the MediaElement is only Silverlight)

    Quick Bits

    Simply setting the Source of a MediaElement to a valid source will stop any current background playback, causing you to fail Marketplace certification, according to section 6.5.1 from the certification guide.

    The Fine Print

    From the certification guide:

    6.5.1  Initial Launch Functionality 

    When the user is already playing music on the phone when the application is launched, the application must not pause, resume, or stop the active music in the phone MediaQueue by calling the Microsoft.Xna.Framework.Media.MediaPlayer class. If the application plays its own background music or adjusts background music volume, it must ask the user for consent to stop playing/adjust the background music (e.g. message dialog or settings menu). 

    Note: This requirement does not apply to applications that play sound effects through the Microsoft.Xna.Framework.Audio.SoundEffect class, as sound effects will be mixed with the MediaPlayer. The SoundEffect class should not be used to play background music. 

    Note: This requirement does not apply to Music + Videos Hub applications that are described in Section 6.4 

    The Setup

    You have a MediaElement which only used to play back one file, so you set the Source in your XAML.

    The Sting

    The user starts playing some music in Zune, then launches your XAP. As soon as your XAML loads and the MediaElement's Source is set, the background music stops playing, even if the MediaElement is not playing. That's right, even if you set AutoPlay = "False", the background music will still be stopped.

    Since you must ask the user for consent, you will have failed certification.

    The Solution

    1. Never set a MediaElement's Source in XAML, unless that XAML is on a page that you navigate to after asking the user for consent.
    2. Check to see if background music is playing and then set the source (in code).
      Note: If you set the source and then immediately call Play(), the Play() will have no affect since the MediaElement will still be in the "Opening" state, instead set "AutoPlay = true" (works from code)
  • Randomisation

    WP7 Marketplace FAQ: Do my free app submissions reset every year?

    • 2 Comments

    Summary

    Yes.

    Seriously?

    Yup, you get 5 free submission credits a year, so every year you could potentially submit another 5 free applications to the marketplace (not to mention the unlimited free updates to existing free applications).

    Can I see how many submission credits I have left?

    Not at this point, though I hope to see this soon. For now, if you can't remember where you're up to, submit a support request and the team will get back to you asap (usually within 24 hours) with an answer.

    Is your head spinning with all the free yet?

  • Randomisation

    WP7 Silverlight TextBoxes No Longer Scroll

    • 0 Comments

    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

    WP7 Marketplace Tip #4: Include Contact info in your next app update

    • 4 Comments

    Summary

    Make sure that you include the app name, version and technical support contact info within your app (or your next update)

    The Fine Print

    Section 5.6 says:

    An application must include the application name, version information, and technical support contact information that are easily discoverable. 

    But my app was improved without this?

    This was a late introduction into the certification guide (a couple of weeks before launch) so it hasn't been enforced up till now. That said, it's now been long enough since release for everyone to be able to have time to add the information so expect to see apps failing if you forget to include this information.

    How do I do this?

    Well, that's the easy part, simply include an About page or Contact Us page. For contact you can send them to a forum link:

    WebBrowserTask browser = new WebBrowserTask();
    browser.URL = "http://somepublisher/forum";
    browser.Show();

    Or an email address:

    EmailComposeTask emailComposeTask = new EmailComposeTask();
    emailComposeTask.To = "Publisher <feedback@publisher.com>";
    emailComposeTask.Subject = "Feedback About [Some App]";
    emailComposeTask.Body = "";
    emailComposeTask.Show();

    When using tasks don't forget to wrap it in a try/catch statement.

  • Randomisation

    WP7 Perf Tip #3: Read the performance document

    • 0 Comments

    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 Marketplace Tip #2.5 - Free App + Updates Policy Clarified (finally)

    • 7 Comments

    It's been a while, and there's been a lot of confusion surrounding this topic of "5 free apps", so here's the final low down:

    • Unlimited number of paid applications
      • This includes updates to said applications
      • A paid application cannot be made free 
    • 5 submissions of free applications
      • Unlimited updates to accepted free apps
      • WARNING: failed submission of free applications will count against the 5 submissions

    So let's walk through a scenario

    A (for "awesome" which seems to be my word of the last couple of months) signs up for the marketplace, pays his $99 (or equivalent in local currency) and gets approved. He then submits "A's Awesome Paid App" which fails submission. He fixes the problems, resubmits and the app is published. Based on feedback he submits 4 subsequent updates. Up to this point A has paid no extra fees.

    A then decides to become philanthropic and submits a free application. The application fails submission - and now A is only left with 4 free submissions. A resubmits and the submission goes through, at which point he starts submitting updates, and has 3 submissions left. No matter how many updates A pushes, they will still have 3 submissions remaining.

  • Randomisation

    Windows Phone Power Tools

    • 0 Comments

    Necessity may be the mother of invention, but it's also often the mother of Open Source tools which are not really reinventing the wheel, but perhaps make our lives just that little bit easier (or more functional). A common pain point, especially as more and more developers move their apps to Mango is testing update scenarios and exploring the IsolatedStorage of a developer app, both extremely handy debugging tools to have that either don't exist (updating developer apps is not really possible) or are very basic (the IsolatedStorage Explorer tool that ships with the SDK).

    To this end, I've published a little Open Source app that I'm dubbing the "Windows Phone Power Tools" that allow you to do just that - update developer xaps, visually explore the IsolatedStorage structure of your apps and a bunch of other small, but handy, features.

    You can check it out on codeplex: http://wptools.codeplex.com 

         

  • Randomisation

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

    • 2 Comments

    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 Perf Tip #2: Know your ProgressBar

    • 0 Comments

    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

    WP Marketplace FAQ: What happens to my apps if I don't renew my subscription

    • 3 Comments

    The Question

    I've signed up for the Windows Phone marketplace and submitted my apps. They're selling well - but I'm not actually planning on doing any more development, so I don't think I need to renew my subscription. What happens if I don't pay the Marketplace renewal fee at the end of the year?

    The Answer

    You'll get a couple of warning emails at the end of the year, but after those if you choose not to renew your subscription your apps will be removed from the Marketplace.

    Will people still be able to use my apps?

    Sure. Microsoft won't revoke the apps from people's phones, but they will remove it from the Marketplace - so no one new will be able to purchase the app (and, obviously, no more revenue for you if it was a paid app).

  • Randomisation

    SL WP7 Toolkit Pro Tip: Set a background on your LongListSelector so that it scrolls correctly

    • 0 Comments

    Got a LongListSelector in your project? Notice that if you try to scroll in blank areas (where the background shows through) it won't react?

    Set:

    Background="{StaticResource PhoneBackgroundBrush}"

    or to whatever colour you prefer and all your problems should go away.

     

  • Randomisation

    WP7 Marketplace Tip #2: 5 Free Apps == 5 Free App *Submissions*

    • 3 Comments

    Updated Policy!

    Sure, the App Hub site says:

    Submit up to five free apps to Windows Phone Marketplace, additional submissions are $19.99 USD

    But here's what it really means:

    Submit up to five free apps (including updates) to the Windows Phone Marketplace, additional submissions (of apps or updates) are $19.99USD

    FTFY

    Seriously

    The policy is simple, just not stated that simply. The first five submissions of any free Windows Phone 7 application - be it a new application or an app update is going to be free, anything further is going to be $19.99USD.

    In reality I don't see this affecting the average casual free app developer out there (since they're not making any revenue off this apps and, (very) generally, not submitting that many updates). It will affect those with free apps that have an alternate revenue source (think advertising or subscription) - but since they're actually making money anyway, the $US19.99 shouldn't be a big deal.

    Stay tuned for an official blog post from the App Hub team at some point in the near future, and a revision to the wording on the website to clear this up...

  • Randomisation

    Marketplace FAQ: What do the different app statuses mean?

    • 2 Comments

    Now that we're out of the woods with the unlimited free app updates policy being clarified, it's time to go back to our Marketplace roots and clear up some misconceptions around the different statuses that your app can have as it passes through certification.

     

    "Submission In Progress" - this is an app that you've started the submission progress for, but have not completed, so the app will not be ready to submit until you go through the full submission form. To do this, click "View details" (under "action" on your dashboard), then click "Edit Submission" (again, under "Action") and run through form. Note that you may encounter a stage where the current form is complete but the "Next" button is not activated (I get this a lot on the screenshot page), simply refill on of the fields (for example, add a dummy screenshot and then remove it).

    "Ready for Testing" - You've successfully passed the first hurdle in getting your app onto the Marketplace, your XAP has been submitted and is (duh!) "Ready for Testing". It will soon be picked up and your status will move to...

    "Testing in Progress" - Your XAP has moved along and is currently being tested. The amount of time it takes to have an app go through will vary depending on the app. I have found that it will tend to come back to you quicker when failing (i.e. as soon as there is a problem) otherwise it usually finishes certification within a couple of days to a week.

    "Ready for Signing" - Congratulations! You've passed testing, your app is certified. It's now going to go through the last technical stage where the XAP is signed and prepared for the Marketplace. This is largely automatic and should be finished within a few hours.

     "Published to Marketplace" - Break out the champagne! Your app is in the marketplace and you're now ready to move on to vNext or appNext. Note that it can take up to 12 hours for your application to show up in the search index, so don't fret if it takes a while. 

    "Certification Failed" - oh oh, an issue was found in your app while running through the certification process. On the submission details page you'll find a testing report in the drop under "action" which will detail exactly what was wrong, and the steps to repro the problem. I'll admit that I was impressed with the reason for one of my failures (clicking multiple times, very quickly, on a button caused the app to crash) and with the way the report detailed the exact problem so that I could find it, fix it and resubmit asap. That said, sometimes there are mistakes made or unclear reports and in this case the support team are your friends.

     

    How long does certification usually take?

    Certification shouldn't take more than 7 days, with the average being a lot lower than that. My record is currently 13 hours (submitted at 2am, on the marketplace by 3pm), though the average that I see reported is 3-4 days.

    What should I do if it's taking more than 7 days?

    First, DON'T PANIC. That said, if you're app is taking more than 10 days, log a support request to find out what's happened. There's a possibility that there was a problem with the file upload which will require you to resubmit your xap, but at least you'll know that things are moving!

    Logging a Support Request

    To log a support request login to create.msdn.com -> My dashboard -> Windows Phone and then hit the "Support" link on the left menu. You should get an initial response within 24 hours (if you haven't gotten a response after 48 hours, log another request).

     

    Run into any marketplace tips / tricks? How about some annoyances? Drop me a comment and I'll see if I can address them in a future blog post (before I head back to writing about perf!).

     

     

  • Randomisation

    Windows Phone System Tray obscures FrameRate counters

    • 0 Comments

    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!

Page 1 of 2 (41 items) 12