<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.microsoft.co.il/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Arik Poznanski&amp;#39;s Blog : Recipe</title><link>http://blogs.microsoft.co.il/blogs/arik/archive/tags/Recipe/default.aspx</link><description>Tags: Recipe</description><dc:language>en</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><item><title>WPF Single Instance Application – Update</title><link>http://blogs.microsoft.co.il/blogs/arik/archive/2011/04/04/wpf-single-instance-application-update.aspx</link><pubDate>Tue, 05 Apr 2011 03:36:40 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:816367</guid><dc:creator>arik</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;Back in &lt;a href="http://blogs.microsoft.co.il/blogs/arik/archive/2010/05/28/wpf-single-instance-application.aspx"&gt;this post&lt;/a&gt; I’ve presented some code that make sure you only have one instance of your application.&lt;/p&gt;  &lt;p&gt;As I’ve said before, I didn’t wrote this code, I just presented it since I came across it in a Microsoft reference application and didn’t want this gem to remain hidden.&lt;/p&gt;  &lt;p&gt;Microsoft recently released a Windows 7 Recipe named “&lt;a href="http://code.msdn.microsoft.com/Windows-7-Taskbar-Single-4120eafd"&gt;Windows 7 Taskbar Single Instance&lt;/a&gt;”, which despite its taskbar-related name is simply a revised implementation of the single instance feature in both .NET and C++. There are well documented samples for both cases. The credit for this recipe goes to &lt;a href="http://blogs.microsoft.co.il/blogs/stiller/"&gt;Eran Stiller&lt;/a&gt; and &lt;a href="http://windowsteamblog.com/members/yochay-kiriaty/"&gt;Yochay Kiriaty&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I advise anyone who needs this feature to work with the new recipe.&lt;/p&gt;  &lt;p&gt;That’s it for now,    &lt;br /&gt;Arik Poznanski.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/04/04/wpf-single-instance-application-update.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/04/04/wpf-single-instance-application-update.aspx&amp;amp;bgcolor=6600FF" /&gt;&lt;/a&gt; &lt;a href="http://dotnetshoutout.com/Submit?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/04/04/wpf-single-instance-application-update.aspx"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/04/04/wpf-single-instance-application-update.aspx" style="border:0px;" /&gt;&lt;/a&gt; &lt;/div&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=816367" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/DEV/default.aspx">DEV</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/WPF/default.aspx">WPF</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Single+Instance/default.aspx">Single Instance</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Recipe/default.aspx">Recipe</category></item><item><title>Shake Gestures Library – A Windows Phone Recipe</title><link>http://blogs.microsoft.co.il/blogs/arik/archive/2011/04/01/shake-gestures-library-a-windows-phone-recipe.aspx</link><pubDate>Sat, 02 Apr 2011 03:34:51 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:815736</guid><dc:creator>arik</dc:creator><slash:comments>9</slash:comments><description>&lt;p&gt;Note: the following article was first published as part of the Windows Phone Recipe “Shake Gestures Library” found &lt;a href="http://create.msdn.com/en-us/education/catalog/article/Recipe_Shake_Gesture_Library"&gt;here&lt;/a&gt;, which I wrote for Microsoft, together with &lt;a href="http://windowsteamblog.com/members/yochay-kiriaty/"&gt;Yochay Kiriaty&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Document Purpose&lt;/h3&gt;  &lt;p&gt;This document introduces a helper library for identifying shake gestures by using the accelerometer built into Windows Phone 7 devices. It explains how to use the library, how the library works internally, and how you can configure the library’s parameters to adapt gesture detection to your needs. &lt;/p&gt;  &lt;h3&gt;Library Features&lt;/h3&gt;  &lt;p&gt;The shake gestures library uses the accelerometer to detect movement in three directions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Left-Right (X direction)&lt;/li&gt;    &lt;li&gt;Top-Bottom (Y direction)&lt;/li&gt;    &lt;li&gt;Forward-Backward (Z direction)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you’re looking for a general purpose shake gesture and don’t care about the direction of the gesture, then you can simply use any combination of one or more of the supported gestures. However, sometimes you need to have better control and to understand if the gesture was in the “right” direction. &lt;/p&gt;  &lt;h3&gt;How to Use the Shake Gesture Library&lt;/h3&gt;  &lt;p&gt;Since the shake gesture library is doing all the heavy lifting for you, using the library requires very little effort from you. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Step 1&lt;/u&gt;&lt;/b&gt;: Add reference to shake gestures library: &lt;b&gt;ShakeGestures.dll&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Step 2&lt;/u&gt;&lt;/b&gt;: Add a &lt;b&gt;using&lt;/b&gt; statement to file header&lt;/p&gt;  &lt;p&gt;   &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:97743ae4-3848-4874-b6a9-f9d45a74c8a0" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; ShakeGestures;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Step 3&lt;/u&gt;&lt;/b&gt;: Register to &lt;b&gt;ShakeGesture&lt;/b&gt; event&lt;/p&gt;  &lt;p&gt;   &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:387a10c3-bcd8-47ca-804c-f5d988b8601f" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#008000;"&gt;// register shake event&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#2b91af;"&gt;ShakeGesturesHelper&lt;/span&gt;.Instance.ShakeGesture += &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;ShakeGestureEventArgs&lt;/span&gt;&amp;gt;(Instance_ShakeGesture);&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#008000;"&gt;// optional, set parameters&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#2b91af;"&gt;ShakeGesturesHelper&lt;/span&gt;.Instance.MinimumRequiredMovesForShake = 5;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Step 4&lt;/u&gt;&lt;/b&gt;: implement the &lt;b&gt;ShakeGesture&lt;/b&gt; event handler from step 3&lt;/p&gt;  &lt;p&gt;   &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9bef5a89-9a93-48d0-bf17-7a310c15e2dd" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Instance_ShakeGesture(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;ShakeGestureEventArgs&lt;/span&gt; e)&lt;br /&gt; {&lt;br /&gt;     _lastUpdateTime.Dispatcher.BeginInvoke(&lt;br /&gt;         () =&amp;gt;&lt;br /&gt;         {&lt;br /&gt;             _lastUpdateTime.Text = &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;.Now.ToString();&lt;br /&gt;             CurrentShakeType = e.ShakeType;&lt;br /&gt;         });&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/p&gt;  &lt;p&gt;The &lt;b&gt;ShakeGestureEventArgs&lt;/b&gt; holds a ShakeType property that identifies the direction of the shake gesture.&lt;/p&gt;  &lt;p&gt;Finally, you need to activate the library, which binds to the phone’s accelerometer and starts listening to incoming sensor input events. &lt;/p&gt;  &lt;p&gt;   &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7acc2026-95c8-46ba-b1b2-483800ea78f5" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#008000;"&gt;// start shake detection&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#2b91af;"&gt;ShakeGesturesHelper&lt;/span&gt;.Instance.Active = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Note&lt;/i&gt;&lt;/b&gt;&lt;i&gt;: You can continue working directly with the phone’s sensor. The ShakeGesturesHelper class doesn’t block any sensor events—it just listens to them.&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Note&lt;/i&gt;&lt;/b&gt;&lt;i&gt;: The &lt;b&gt;ShakeGesture&lt;/b&gt; event arrives on a thread different from the UI thread, so if you want to update the UI from this event you should dispatch your code to run on the UI thread. This can be done by using the method myControl.&lt;/i&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.begininvoke(VS.95).aspx"&gt;&lt;i&gt;Dispatcher.BeginInvoke&lt;/i&gt;&lt;/a&gt;&lt;i&gt;(), where myControl is the control you want to update.&lt;/i&gt;&lt;/p&gt;  &lt;h3&gt;How Does the Shake Gesture Library Work?&lt;/h3&gt;  &lt;p&gt;We need to figure out what a shake gesture is and how to identify a shake when it occurs. Then we need to classify the shake according to the gesture direction. &lt;/p&gt;  &lt;p&gt;The accelerometer sensor in a Windows Phone measures the gravity forces applied on the phone and reports an &lt;b&gt;AccelerometerReading &lt;/b&gt;event about 50 times per second. When you move the phone up and down in 3D space, you’re getting a lot of readings (the sensors are quite noisy), and you don’t really know the phone’s orientation or the distance that the phone moved, since all you have are changes in the relative gravity force on the phone during a given period of time. &lt;/p&gt;  &lt;p&gt;With that in mind, we set out to create a simple, high-performance shake gesture library, and came up with the following shake gestures detection process:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Noise reduction&lt;/li&gt;    &lt;li&gt;Segmentation into &amp;quot;Shake&amp;quot; and &amp;quot;Still&amp;quot; signal segments&lt;/li&gt;    &lt;li&gt;Shake direction classification&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;We report sensor readings as vectors, since we obtain 3-axis readings (X, Y, and Z, with each having a double value associated with it). We can set the initial point to (0, 0, 0), hence a &lt;a href="http://en.wikipedia.org/wiki/Euclidean_vector"&gt;vector&lt;/a&gt;. &lt;/p&gt;  &lt;h4&gt;Noise Reduction&lt;/h4&gt;  &lt;p&gt;Before performing gesture detection, the noise must be removed from the accelerometer’s input vectors. This is done by passing the raw input vectors through a low-pass filter. This smooth the signal so that it ignores small changes and only takes into account any “large enough” changes. We’re using an existing noise reduction implementation by Dave Edson. For more details on Dave’s algorithm, check out this &lt;a href="http://windowsteamblog.com/windows_phone/b/wpdev/archive/2010/09/08/using-the-accelerometer-on-windows-phone-7.aspx"&gt;blog post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/arik/image_08F63210.png"&gt;&lt;img style="margin:0px auto;display:block;float:none;" title="image" alt="image" src="http://blogs.microsoft.co.il/blogs/arik/image_thumb_3BE5C277.png" width="355" height="311" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;Figure 1: Before noise reduction&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/arik/image_40E80026.png"&gt;&lt;img style="margin:0px auto;display:block;float:none;" title="image" alt="image" src="http://blogs.microsoft.co.il/blogs/arik/image_thumb_5113C81F.png" width="437" height="311" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;Figure 2: After noise reduction&lt;/p&gt;  &lt;p&gt;As you can see, the signal after noise reduction is much cleaner and easier to work with. &lt;/p&gt;  &lt;h4&gt;Segmentation into Shake and Still Signal Segments&lt;/h4&gt;  &lt;p&gt;After cleaning the signal, our next step is to separate shake and still segments. Basically, we want to identify shake segments when the following conditions are satisfied:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The magnitude of one or more of the vectors (X, Y, or Z) crosses a certain threshold. &lt;/li&gt;    &lt;li&gt;The vector stays above this threshold long enough so that we don’t mistake a one-time blip for a shake. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Note&lt;/i&gt;&lt;/b&gt;&lt;i&gt;: We don’t use a system timer to measure time. Instead, we depend on the fact that the Windows Phone sensor generates about 50 events per second, so the time between each event is around 20 msec. Therefore, five events total roughly 100 msec&lt;/i&gt;. You’ll see in the code that we measure event intervals and not real world clock time.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/arik/image_3D1A3589.png"&gt;&lt;img style="margin:0px auto;display:block;float:none;" title="image" alt="image" src="http://blogs.microsoft.co.il/blogs/arik/image_thumb_0F88EFF9.png" width="529" height="432" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;Figure 3: Signal segmentation&lt;/p&gt;  &lt;p&gt;Ignore for a second how we calculate vector magnitudes; we’ll address that topic in the next section. For now, look at Figure 3. You can see from the green line pattern that it’s very clear when the phone was in a shake segment and when it was in a still segment. Therefore, our goal is to be able to understand when a series of vectors represents a shake segment. Once we identify a shake segment, we’ll further process it to extract the shake type and raise the shake event. &lt;/p&gt;  &lt;h5&gt;Calculating Gravitation Vectors&lt;/h5&gt;  &lt;p&gt;To start with, we need a reference point that reflects the still state of the phone. The Still segment is used to compute something we call the &lt;b&gt;last-known-gravitation-vector&lt;/b&gt;. The last-known-gravitation-vector will be used later to eliminate the effect of gravitation when classifying the shake type.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Note&lt;/i&gt;&lt;/b&gt;&lt;i&gt;: We can&amp;#39;t assume that the gravitation vector will always have the value (0,-1, and 0) for two reasons:&lt;/i&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Gravity isn’t exactly &lt;a href="http://en.wikipedia.org/wiki/Standard_gravity"&gt;1G&lt;/a&gt; everywhere on earth. It varies somewhat according to location and altitude.&lt;/li&gt;    &lt;li&gt;The direction of the gravity vector depends on how you hold your phone. If you rotate it, the direction varies. If you’re moving, your hand direction varies.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;To calculate the gravitation vector, we take the most recent vectors in the still signal (&lt;a&gt;MaximumStillVectorsNeededForAverage&lt;/a&gt; parameter) and average the vectors that have very low magnitude (&lt;a&gt;StillMagnitudeWithoutGravitationThreshold&lt;/a&gt; parameters. In case we don&amp;#39;t have enough still vectors for a representative sample (&lt;a&gt;MinimumStillVectorsNeededForAverage&lt;/a&gt; parameter), we abort the calculation, since we won&amp;#39;t get a valid gravitation vector. &lt;/p&gt;  &lt;p&gt;The gravitation vector is re-calculated for each new still segment that we get, to account for any changes in how you hold your phone. Remember that we’re looking for real time effects; therefore, we need to maintain an accurate state of the current gravitation forces that are affecting the phone. &lt;/p&gt;  &lt;h5&gt;Finding Signal Boundaries&lt;/h5&gt;  &lt;p&gt;Now, let’s assume the user starts shaking his phone. We need to find the shake segment starting and ending points. To do so, we use the following algorithm:&lt;/p&gt;  &lt;p&gt;There are only two possible states: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Shake state&lt;/b&gt; – Indicates that we’re currently in the middle of a shake signal&lt;/li&gt;    &lt;li&gt;&lt;b&gt;Still state&lt;/b&gt; – Indicates that we’re currently in the middle of a still signal (that is, not in the middle of a shake signal)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Based on the current state and the input vector type, we decide what the next step is. Each time we get a new input vector from the accelerometer (after noise reduction), we check whether the vector magnitude is equal or larger than a certain shake threshold &lt;a&gt;ShakeMagnitudeWithoutGravitationThreshold&lt;/a&gt; parameter. If it’s larger, then this input vector is addressed as a potential shake vector. Otherwise, it’s considered a still vector. &lt;/p&gt;  &lt;p&gt;Per each input vector and the current “shake” state we use the following state-machine to determine the next state…&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Condition:&lt;/b&gt; The current state of the phone is still, and the new vector has a still magnitude value.&lt;/li&gt;    &lt;li&gt;&lt;b&gt;Operation: &lt;/b&gt;Add the vector to the still signal array (the array is a cyclic array).&lt;/li&gt;    &lt;li&gt;&lt;b&gt;Condition:&lt;/b&gt; The current state of the phone is still, and the new input vector has a magnitude that is higher than the minimum shake threshold.&lt;/li&gt;    &lt;li&gt;&lt;b&gt;Operation: &lt;/b&gt;Set shake state, process still signal, add vector to shake signal array (this doesn’t mean that we identified a shake, we’re just adding it to the array for further processing later).&lt;/li&gt;    &lt;li&gt;&lt;b&gt;Condition: &lt;/b&gt;The current phone state is shake, and the new input vector has a shake magnitude.&lt;/li&gt;    &lt;li&gt;&lt;b&gt;Operation: &lt;/b&gt;Add vector to shake signal, try to process shake signal array. Here we’re actually trying to identify a shake, since we already got a few shake vectors in the array. Again, we need to wait for the minimum amount of shake vector before we can start processing a shake single. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Condition:&lt;/b&gt; The current phone state is shake, and the new input vector has a still magnitude (it’s below the minimum shake magnitude).&lt;/li&gt;    &lt;li&gt;&lt;b&gt;Operation:&lt;/b&gt; Add vector to shake signal, unless we’ve already received too many sequential still vectors (&lt;a&gt;StillCounterThreshold &lt;/a&gt;parameter), in which case move the still vectors to the still signal and change the phone state to still state.&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Shake Type Classification&lt;/h4&gt;  &lt;p&gt;It’s time to dive into the actual vector processing. The following describes the algorithm we’re using, but for performance reasons the code performs some of the processing while the shake vectors are being collected, but the idea remains the same.&lt;/p&gt;  &lt;h5&gt;Neutralizing Gravitation Effects (Removing Earth Gravity Effects)&lt;/h5&gt;  &lt;p&gt;All input vectors include the earth’s gravitation forces. And since we don’t have any idea about the position of your phone in 3D space, we don’t know which of the vectors (X, Y, or Z) is affected by the earth’s gravity. Therefore, we need to remove the earth’s gravity effect.&lt;/p&gt;  &lt;p&gt;To eliminate the effect of gravity, we first reduce the last known gravitation vector from all the vectors in the shake signal. In this way, when we get acceleration in some axis we can be certain that the user moved the phone along that axis instead of wondering whether this is just the force of gravity trying to fool us. Therefore, for each input vector we’re subtracting the last known gravity vector. &lt;/p&gt;  &lt;h5&gt;Finding Shake Main Direction&lt;/h5&gt;  &lt;p&gt;Now we want to find the main direction of the shake signal, which can be one of the following three directions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;X (left-right)&lt;/li&gt;    &lt;li&gt;Y (top-bottom)&lt;/li&gt;    &lt;li&gt;Z (forward-backward)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;To do this, we first need to find the main direction of each vector in the shake signal. We do this by checking which of the vector products has the biggest absolute value. To get a better feeling of why we’re breaking the vector into its products, let’s review a 2D vector. As you can see in Figure 4, the red vector products are broken into the X and Y values [Red value = sqrt(pow(x,2) + pow(y,2))].&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/arik/image_2F27A3F4.png"&gt;&lt;img style="margin:0px auto;display:block;float:none;" title="image" alt="image" src="http://blogs.microsoft.co.il/blogs/arik/image_thumb_4D91E4DD.png" width="249" height="226" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;Figure 4: Illustration of classifying a 2D vector&lt;/p&gt;  &lt;p&gt;It’s clear that the red vector should be classified as an X axis vector, because its X product is much stronger than its Y product. The same methodology is implemented in the library for 3D vectors.&lt;/p&gt;  &lt;p&gt;At this stage, we’ve got a vector that isn’t affected by the earth’s gravity, we’ve broken the vector into its products, and we know the main direction of the vector. &lt;/p&gt;  &lt;p&gt;Our next step is to create a histogram of the vectors’ products, and then to select the direction with the most products in it. Remember, we started with a vector whose magnitude is strong enough to be considering a &lt;b&gt;shake &lt;/b&gt;vector. We removed the earth’s gravity effect, and we broke it into its distinct products, and classified them. For example, Figure 5 shows a histogram of a shake signal that has most of its vectors pointing in X direction, hence the shake signal’s main direction will be X. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/arik/image_1DF3C651.png"&gt;&lt;img style="margin:0px auto;display:block;float:none;" title="image" alt="image" src="http://blogs.microsoft.co.il/blogs/arik/image_thumb_431110BD.png" width="260" height="289" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;Figure 5: Histogram of vector directions in a shake signal&lt;/p&gt;  &lt;p&gt;To prevent weak vectors (&lt;a&gt;WeakMagnitudeWithoutGravitationThreshold&lt;/a&gt; parameter) that got into the shake signal from affecting the histogram result, we’ll only consider vectors above a certain threshold when calculating the histogram.&lt;/p&gt;  &lt;p&gt;In addition, we’ll consider the histogram result as valid only if the number of vectors in the main direction passes a certain threshold (&lt;a&gt;MinimumShakeVectorsNeededForShake&lt;/a&gt; parameter). This will enable us to eliminate false results due to histograms done on small amounts of data.&lt;/p&gt;  &lt;h5&gt;Recognizing the Gesture &lt;/h5&gt;  &lt;p&gt;Up until now, we’ve identified a movement of the phone in 3D space that’s fast (powerful) enough to be consider a shake. Basically, we know the shake signal’s axis, but that isn’t sufficient. In order to make sure the movement we detected is really a shake gesture, and not just a random (single) movement in one direction, we need to count several intervals of movement and, more importantly, changes in the vector direction. A shake is defined as a movement of the phone on one axis back and forth a few times.&lt;/p&gt;  &lt;p&gt;To check whether the shake signal is a shake gesture, we’ll check the sign of the main direction coordinate. For example, if we found that the main direction of our shake signal was X, then we’ll inspect the sign of the X products of all the vectors in the signal. On a real shake gesture, we expect the sign to change a few times, since we move the phone back and forth and thus keep changing the force (acceleration), which translates to a direction change. &lt;/p&gt;  &lt;p&gt;For example, in the following figure we see a normalized (without gravitation) shake signal of a real shake gesture. You can clearly see the main direction being Z, and the Z values go back and forth between positive and negative.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/arik/image_682E5B29.png"&gt;&lt;img style="margin:0px auto;display:block;float:none;" title="image" alt="image" src="http://blogs.microsoft.co.il/blogs/arik/image_thumb_2C8E4C69.png" width="385" height="231" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="center"&gt;Figure 6: Example of a shake vector&lt;/p&gt;  &lt;p&gt;In order to identify the gesture, we’ll count how many times the X values goes from positive to negative and back. If the count is bigger than &lt;a&gt;MinimumRequiredMovesForShake&lt;/a&gt;, we’ll finally raise the shake gesture event!&lt;/p&gt;  &lt;h3&gt;Configuring Parameters&lt;/h3&gt;  &lt;p&gt;During the coding and testing of the library, we found that shake is very individualized. It depends on the nature of the application and the actual shake gesture made by the phone’s user. There are alternative algorithms available that are adaptive and learning algorithms. While these might be more accurate, they require a learning phase that we didn’t want to force on the end user and on the developer building the app. Therefore, we give you plenty of different properties to tweak and tune for your own purposes. &lt;/p&gt;  &lt;p&gt;These parameters control various aspects of the gesture detection algorithm. By changing these parameters, you can change your application’s sensitivity to shakes and to the duration of a shake. All parameters have default values kept as constants in the library.&lt;/p&gt;  &lt;p&gt;The following section describes the available parameters. Each parameter is mentioned in context in the above algorithm.&lt;/p&gt;  &lt;h4&gt;ShakeMagnitudeWithoutGravitationThreshold&lt;/h4&gt;  &lt;p&gt;&lt;b&gt;Description&lt;/b&gt;: Any vector that has a magnitude (after reducing gravitation force) bigger than this parameter value is considered as a shake vector.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Default value&lt;/b&gt;: 0.2&lt;/p&gt;  &lt;h4&gt;&lt;a name="_StillCounterThreshold"&gt;&lt;/a&gt;StillCounterThreshold&lt;/h4&gt;  &lt;p&gt;&lt;b&gt;Description&lt;/b&gt;: This parameter determines how many consecutive still vectors are required to stop a shake signal.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Default value&lt;/b&gt;: 20 (about 400 msec)&lt;/p&gt;  &lt;h4&gt;&lt;a name="_StillMagnitudeWithoutGravitationThr"&gt;&lt;/a&gt;StillMagnitudeWithoutGravitationThreshold&lt;/h4&gt;  &lt;p&gt;&lt;b&gt;Description&lt;/b&gt;: This parameter determines the maximum allowed magnitude (after reducing gravitation) for a still vector to be considered. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Default value&lt;/b&gt;: 0.02&lt;/p&gt;  &lt;h4&gt;&lt;a name="_MaximumStillVectorsNeededForAverage"&gt;&lt;/a&gt;MaximumStillVectorsNeededForAverage&lt;/h4&gt;  &lt;p&gt;&lt;b&gt;Description&lt;/b&gt;: The maximum number of still vectors needed to create a still vector average. Instead of averaging the entire still signal, we just look at the top recent still vectors. This is performed as runtime optimization.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Default value&lt;/b&gt;: 20&lt;/p&gt;  &lt;h4&gt;&lt;a name="_MinimumStillVectorsNeededForAverage"&gt;&lt;/a&gt;MinimumStillVectorsNeededForAverage&lt;/h4&gt;  &lt;p&gt;&lt;b&gt;Description&lt;/b&gt;: The minimum number of still vectors needed to create a still vector average. Without enough vectors, the average won’t be stable and thus will be ignored.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Default value&lt;/b&gt;: 5&lt;/p&gt;  &lt;h4&gt;&lt;a name="_MinimumShakeVectorsNeededForShake"&gt;&lt;/a&gt;MinimumShakeVectorsNeededForShake&lt;/h4&gt;  &lt;p&gt;&lt;b&gt;Description&lt;/b&gt;: Determines the number of shake vectors needed in order to recognize a shake.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Default value&lt;/b&gt;: 10&lt;/p&gt;  &lt;h4&gt;&lt;a name="_WeakMagnitudeWithoutGravitationThre"&gt;&lt;/a&gt;WeakMagnitudeWithoutGravitationThreshold&lt;/h4&gt;  &lt;p&gt;&lt;b&gt;Description&lt;/b&gt;: Shake vectors with a magnitude lower than this parameter won’t be considered for gesture classification.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Default value&lt;/b&gt;: 0.2&lt;/p&gt;  &lt;h4&gt;&lt;a name="_MinimumRequiredMovesForShake"&gt;&lt;/a&gt;MinimumRequiredMovesForShake&lt;/h4&gt;  &lt;p&gt;&lt;b&gt;Description&lt;/b&gt;: Determines the number of moves required to get a shake signal.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Default value&lt;/b&gt;: 3&lt;/p&gt;  &lt;h3&gt;Summary&lt;/h3&gt;  &lt;p&gt;In this document we showed how you can use the Shake Gestures Library in your application. We did an in-depth tour of the algorithms used for recognizing shakes. Finally, we skimmed through the various parameters that you can change to better fit gesture detection to your application’s needs. &lt;/p&gt;  &lt;p&gt;Shake it up!&lt;/p&gt;  &lt;p&gt;That’s it for now,    &lt;br /&gt;Arik Poznanski.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/04/01/shake-gestures-library-a-windows-phone-recipe.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/04/01/shake-gestures-library-a-windows-phone-recipe.aspx&amp;amp;bgcolor=6600FF" /&gt;&lt;/a&gt; &lt;a href="http://dotnetshoutout.com/Submit?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/04/01/shake-gestures-library-a-windows-phone-recipe.aspx"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/04/01/shake-gestures-library-a-windows-phone-recipe.aspx" style="border:0px;" /&gt;&lt;/a&gt; &lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=172641" rel="tag" style="display:none;"&gt;CodeProject&lt;/a&gt; &lt;/div&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=815736" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/DEV/default.aspx">DEV</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Windows+Phone+7/default.aspx">Windows Phone 7</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Recipe/default.aspx">Recipe</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Accelerometer/default.aspx">Accelerometer</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Shake/default.aspx">Shake</category></item><item><title>Ways to Load Applications Faster – A Windows Phone Recipe</title><link>http://blogs.microsoft.co.il/blogs/arik/archive/2011/03/25/ways-to-load-applications-faster-a-windows-phone-recipe.aspx</link><pubDate>Fri, 25 Mar 2011 05:05:12 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:813930</guid><dc:creator>arik</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;Note: the following article was first published as part of the Windows Phone Recipe “Ways to Load Applications Faster” found &lt;a href="http://create.msdn.com/en-us/education/catalog/article/Recipe_Faster_Loading_Times"&gt;here&lt;/a&gt;, which I wrote for Microsoft, together with &lt;a href="http://windowsteamblog.com/members/yochay-kiriaty/"&gt;Yochay Kiriaty&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Purpose of This Document&lt;/h3&gt;  &lt;p&gt;This document introduces the loading procedure for Windows Phone Silverlight applications. It explains common mistakes that application developers make during application launch, and how those errors can increase the total application load time and harm the user experience. Next, this document describes some possible solutions for overcoming long load times and explains their implementation. &lt;/p&gt;  &lt;p&gt;Application startup is also discussed in &lt;a href="http://msdn.microsoft.com/en-us/library/ff967560(v=VS.92).aspx#BKMK_Startup"&gt;Performance Considerations in Applications for Windows Phone&lt;/a&gt;. That paper provides excellent background information and can help make your Windows Phone applications shine. &lt;/p&gt;  &lt;h3&gt;Windows Phone Application Flow: Launching, Running, and Closing&lt;/h3&gt;  &lt;p&gt;We can&amp;#39;t talk about proper loading techniques and optimizing application startup time without explaining Windows Phone application lifetime events. The following section providers a short overview; for more detailed information, see &lt;a href="http://msdn.microsoft.com/en-us/library/ff769557(VS.92).aspx"&gt;Execution Model for Windows Phone&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Windows Phone provides developers with a series of events and APIs for handling tombstoning and other application state changes, which include launching and closing. The &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell.phoneapplicationservice(VS.92).aspx"&gt;PhoneApplicationService&lt;/a&gt; class, found in the &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.shell(VS.92).aspx"&gt;Microsoft.Phone.Shell&lt;/a&gt; namespace, provides access to various aspects of the application’s lifetime, including management of the application’s state when it becomes active or inactive.&lt;/p&gt;  &lt;p&gt;The &lt;b&gt;PhoneApplicationService&lt;/b&gt; class exposes four main lifetime events. For any auto- generated Windows Phone application (generated by &lt;b&gt;Visual Studio 2010 Express for Windows Phone&lt;/b&gt; or &lt;b&gt;Visual Studio 2010&lt;/b&gt;), the &lt;b&gt;App.xaml.cs&lt;/b&gt; file includes four methods directly related to the execution model. These methods are your application handlers for the lifetime events exposed by the &lt;b&gt;PhoneApplicationService&lt;/b&gt; class:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Application_Launching &lt;/li&gt;    &lt;li&gt;Application_Activated &lt;/li&gt;    &lt;li&gt;Application_Deactivated &lt;/li&gt;    &lt;li&gt;Application_Closing &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The names of these methods are self-explanatory. However, there are some subtleties that we need to cover:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Application Launching&lt;/b&gt; – A Windows Phone application is considered to be launched when it’s started by a means other than by the user pressing the Back button to return to a previous application. An application is launched when the user taps the entry for the application in the phone’s applications list or the tile for the application on Start. An application can also be launched when the user taps a toast notification. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Application Deactivated&lt;/b&gt; occurs when a different application takes control of the foreground; for example, when the user launches a chooser or presses the Start button. In both cases, your application will be deactivated; the Deactivated event is raised, as opposed to the Closing event when your application exits. However, unlike an application that’s closed, a deactivated application will most likely get tombstoned. Don’t become confused: A tombstoned application’s underlying process still gets terminated, so your application does “close.” But unlike a closed application (which has exited), where the Windows Phone operating system removes any trace of the application from memory, in the deactivated scenario the Windows Phone operating system stores a record (a tombstone) of the application&amp;#39;s state. Basically, the Windows Phone operating system keeps a tombstone of the application that becomes part of the phone’s application back-stack, which is a journal that enables the use of the Back button to enhance navigation functionality. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Application Activated&lt;/b&gt; – After an application has been deactivated, it’s possible that it will never be reactivated. However, it’s also possible that the user will return to the application by pressing the Back button enough times to reach the application. When the user returns to a deactivated application, it’s reactivated and the Activated event is raised. Windows Phone then navigates to the last page viewed by the user in order to give the user the feeling that the application is simply continuing. Note that unlike Launching, some data objects in an Activated application might still be initialized. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Application Closing&lt;/b&gt; is simply the outcome of the user pressing the Back button enough times to navigate backwards through the pages of your application, and past the application’s first page. Currently, this is the only way for a user to exit your application. Once your application is closed, its process is terminated, the operating system removes any trace of that application from its memory, and there’s no way to return to the application other than by launching a new instance. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Note that Launching and Activated events are mutually exclusive, as are the Deactivated and Closing events.&lt;/p&gt;  &lt;p&gt;These events play a critical role in your application’s loading and closing times. Loading time also applies during application tombstoning and, more importantly, for applications resuming from tombstone.&lt;/p&gt;  &lt;p&gt;One last note before we continue. There’s a certain sequence of methods that gets called during launching and tombstoning. This method sequence is critical for optimizing load time operations. &lt;/p&gt;  &lt;p&gt;For the most part, when your application is launching or returning from tombstone, the following methods are being executed in the following order:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Application constructor –App() found in App.xaml.cs &lt;/li&gt;    &lt;li&gt;Application launching – Application_Launching found in App.xaml.cs &lt;/li&gt;    &lt;li&gt;Your application’s “first page” constructor &lt;/li&gt;    &lt;li&gt;Your application’s “first page” OnNavigatedTo method &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Note&lt;/i&gt;&lt;/b&gt;&lt;i&gt;: When returning from tombstone, the “first page” is the last page the application was showing, and not necessarily the actual first page of the application.&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Note:&lt;/i&gt;&lt;/b&gt;&lt;i&gt; When your application returns from a tombstone state, this entire sequence is executed. However, in cases where tombstoning is relaxed, and your application is deactivated but not tombstoned, the Application constructor and the Page constructor aren’t executed. For additional information about Application Lifetime events and tombstoning, see &lt;/i&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ff769557(VS.92).aspx"&gt;Execution Model for Windows Phone&lt;/a&gt;&lt;i&gt;.&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;Application &lt;b&gt;launch time&lt;/b&gt; is defined from the time Windows Phone loads your application into memory and starts executing the application constructor (the first method in the sequence) until the end of the execution of the OnNavigatedTo method first page. &lt;/p&gt;  &lt;h4&gt;Startup and Shutdown Times&lt;/h4&gt;  &lt;p&gt;Windows Phone enforces a series of time limits on application startup and shutdown in order to preserve a consistent and responsive user experience across the phone’s built-in applications and 3&lt;sup&gt;rd&lt;/sup&gt;-party applications. If your application exceeds the allowed time for startup or shutdown, it will be forcibly terminated and removed from the back-stack. This means your application doesn’t get tombstoned, it’s simply terminated, and the user can’t use the back button to reactivate it. The following table outlines launch shutdown, deactivated, and reactivated times:&lt;/p&gt;  &lt;p align="left"&gt;Table 1-1. Application Startup / Shutdown times &lt;/p&gt;  &lt;p align="left"&gt;   &lt;table cellspacing="0" cellpadding="0"&gt;       &lt;tr&gt;         &lt;td valign="top"&gt;           &lt;p align="left"&gt;&lt;strong&gt;Application Event&lt;/strong&gt;&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;&lt;strong&gt;Limit&lt;/strong&gt;&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top"&gt;           &lt;p&gt;Starting the application (application Launching event)&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;10 sec&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top"&gt;           &lt;p&gt;Forward navigating away from the application (application Deactivated event)&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;10 sec&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top"&gt;           &lt;p&gt;Returning to the application using the Back key (application Activated event)&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;10 sec&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top"&gt;           &lt;p&gt;Exiting from the application (application Closing event)&lt;/p&gt;         &lt;/td&gt;          &lt;td valign="top"&gt;           &lt;p&gt;10 sec&lt;/p&gt;         &lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/p&gt;  &lt;p&gt;You can see that you have up to 10 seconds of real-world time (this doesn’t mean that you have 100% of the CPU for 10 seconds) to handle each application lifetime event. If for some reason your code takes longer than 10 seconds to execute, the Windows Phone system will terminate your application. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Note:&lt;/i&gt;&lt;/b&gt;&lt;i&gt; Besides the operating system safeguards, part of the Marketplace ingestion process is to check the time it takes to launch and to return from tombstoning. The user experience guidelines are even stricter, and require less than 10 seconds to properly launch your application. According to &lt;/i&gt;&lt;a href="http://go.microsoft.com/?linkid=9730558"&gt;&lt;i&gt;Windows Phone 7 Application Certification Requirements&lt;/i&gt;&lt;/a&gt;&lt;i&gt;, the application must render the first screen within five seconds after launch, even when there’s a splash image. Therefore, optimizing and understanding the load sequence are critical to your application’s success.&lt;/i&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Startup time&lt;/b&gt; – Includes launching or returning to a tombstoned application. It’s the time from when your application process starts executing until your application becomes active or visible. Your application becomes visible only after the execution of the OnNavigatedTo method ends of the page the application navigates to upon launch or returning from tombstoning. Until then, the application’s splash screen is displayed and the application isn’t considered active. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Shutdown time&lt;/b&gt; – Includes deactivating and exiting from the application, and mostly consists of the time from when the forward navigation was invoked until the Deactivated or Closing methods execution ends. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Demonstrating the Problem&lt;/h3&gt;  &lt;p&gt;As explained in the previous section, the application must complete its loading and display its first page (or any page when returning from tombstoning) within 10 seconds or the OS will kill the process. Moreover, even if your application launches in five or eight seconds, you still need to optimize the user experience by loading the application and displaying something as soon as possible; otherwise, the impatient user might tap the Back or Windows button to navigate away from your application. &lt;/p&gt;  &lt;p&gt;So let&amp;#39;s see how easy it is to create a well-behaved application. In the following demo we’ll create a Windows Phone Silverlight application that needs to execute some long operations while loading.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Note&lt;/i&gt;&lt;/b&gt;&lt;i&gt;: Our example application describes a very simple scenario for a Silverlight application that displays some information on the first page. This information should be obtained from some web service or local storage. To illustrate the problem, we create a fake workload that intentionally takes about 10 seconds to complete. &lt;/i&gt;&lt;/p&gt;  &lt;p&gt;To simulate a long operation, we’ll simply trigger a function that sleeps for a second and reiterate that 10 times. (See the MyService.Init methods below.)&lt;/p&gt;  &lt;p&gt;To experience this firsthand, simply follow these steps: &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Step 1&lt;/u&gt;: Create a Windows Phone Application&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Step 2&lt;/u&gt;: Create long workloads &lt;/b&gt;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:210e5434-9b8b-4755-9b79-5440c45e1017" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; NumberOfIterations = 10;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Init()&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; NumberOfIterations; ++i)&lt;br /&gt;         {&lt;br /&gt;             &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(1));&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Init(&lt;span style="color:#2b91af;"&gt;Dispatcher&lt;/span&gt; dispatcher)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; NumberOfIterations; ++i)&lt;br /&gt;         {&lt;br /&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (dispatcher != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;             {&lt;br /&gt;                 dispatcher.BeginInvoke(() =&amp;gt;&lt;br /&gt;                 {&lt;br /&gt;                     &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(1));&lt;br /&gt;                 });&lt;br /&gt;             }&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Essentially, both methods perform the same operation: they sleep for about 10 seconds to mimic a long workload. The second Init method accepts a Dispatcher as an input parameter that we use each in sleep period. This forces a sync with the main user interface (UI) page (since that’s the dispatcher we’re passing in), as it isn’t reasonable to write code that completely blocks the UI thread for 10 seconds. Eventually, calling the dispatcher allows Windows Phone to terminate faster, as you’ll see later.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Step 3&lt;/u&gt;: Call the long workloads from various locations in your application&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Call the function &lt;b&gt;MyService.Init&lt;/b&gt; from either one or all five methods: &lt;/p&gt;  &lt;p&gt;1.&amp;#160; App constructor&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e9724412-2670-47de-932b-a44163352711" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;partial&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;App&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Application&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; App()&lt;br /&gt;     {&lt;br /&gt;         ...&lt;br /&gt; &lt;br /&gt;         MyService.Init();&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     ...&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;2.&amp;#160; Application &lt;b&gt;Launching&lt;/b&gt; event&lt;/p&gt;  &lt;p&gt;This event is raised when the user launches the application by tapping on the application’s icon.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:867c8b36-ef58-4ef8-a84b-794d4797ace2" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;partial&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;App&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Application&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     ...&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Application_Launching(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;LaunchingEventArgs&lt;/span&gt; e)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.Init();&lt;br /&gt;     }&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;3.&amp;#160; Application &lt;b&gt;Activated&lt;/b&gt; event&lt;/p&gt;  &lt;p&gt;This event is raised when the user taps the Back key to return to the application, or after returning from a chooser or a launcher.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:63779760-057b-4ef5-b49e-6d994486f0f5" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;partial&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;App&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Application&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     ...&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Application_Activated(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;ActivatedEventArgs&lt;/span&gt; e)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.Init();&lt;br /&gt;     }&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;4.&amp;#160; Page constructor &lt;/p&gt;  &lt;p&gt;This function is called when the &lt;b&gt;Page&lt;/b&gt; class is created.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a587e019-efa2-42f9-8023-c0a4697ea71c" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;partial&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MainPage&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;PhoneApplicationPage&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; MainPage()&lt;br /&gt;     {&lt;br /&gt;         InitializeComponent();&lt;br /&gt;             &lt;br /&gt;         &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.Init(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Dispatcher); &lt;span style="color:#008000;"&gt;//Or you can run MyService.Init();&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     ...&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;5.&amp;#160; Page &lt;b&gt;OnNavigatedTo&lt;/b&gt; method&lt;/p&gt;  &lt;p&gt;This function is called when the page is navigated to, either from another page or when the application gets launched/activated.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Note&lt;/b&gt;: &lt;i&gt;The problem shown in this demo also can occur when your application comes back from a tombstone state, so you need to make sure you don&amp;#39;t have lots of work in the constructor and &lt;b&gt;OnNavigatedTo&lt;/b&gt; functions of any of your pages in the application.&lt;/i&gt;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2a29894b-7c27-4547-a7e3-3672376e3b88" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;partial&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MainPage&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;PhoneApplicationPage&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     ...&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; OnNavigatedTo(&lt;span style="color:#2b91af;"&gt;NavigationEventArgs&lt;/span&gt; e)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.Init(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Dispatcher); &lt;span style="color:#008000;"&gt;//Or you can run MyService.Init();&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;     }&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&lt;b&gt;&lt;u&gt;Step 4&lt;/u&gt;: Run your application&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Simply run your application from your phone and observe that the operating system terminates your application. When it terminates your application depends on specific implementation criteria, as explained below. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Note&lt;/i&gt;&lt;/b&gt;&lt;i&gt;: To test whether the Windows Phone terminates your application when your application’s load time exceeds the 10-second limit, you must run your application on a real device &lt;u&gt;without&lt;/u&gt; attaching the debugger. You need to deploy the application to the phone and then run it. Don’t run the application from Visual Studio, as when the debugger is attached (either to your Windows Phone device or to Windows Phone emulator); the relevant watchdog timers are disabled and the application will simply load after all the fake workload methods complete their task. &lt;/i&gt;&lt;/p&gt;  &lt;p&gt;If you use the Init without the dispatcher, then the sleep (on the main UI thread) prevents any operations from executing on the main thread (which is the main application thread). This is rather extreme and doesn’t represent a real-life scenario. So we’ve added a call to the dispatcher during each sleep period in order to sync back to the UI thread, and give the Silverlight runtime a chance to do what it’s supposed to do (terminate your application). Therefore, you’ll notice that when calling the MyService.Init method without the parameter, the application will eventually get terminated, but only after all the sleep periods occur (depending on how many times you called the MyService.Init method). When you pass the dispatcher as an input param (this is only possible in the MainPage), you’ll notice that your application terminates faster. &lt;/p&gt;  &lt;p&gt;Try removing the MyService.Init method from the Application constructor and Launching method, but leave them in the MainPage constructor and OnNavigatedTo methods. You’ll see that it still takes about 11 or 12 seconds for the operating system to terminate your application. This again proves that it takes only one misbehaving method to significantly impair your application’s load time. &lt;/p&gt;  &lt;h3&gt;The Solution – Optimizing Your Application Load Time&lt;/h3&gt;  &lt;p&gt;Now that you understand the Windows Phone Silverlight application launch sequence and the problem of long launch times, it’s time to present some ways to optimize your application load times. &lt;/p&gt;  &lt;p&gt;The solution is composed of four action items:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Use a splash image &lt;/li&gt;    &lt;li&gt;Defer work &lt;/li&gt;    &lt;li&gt;Do work on a background Thread &lt;/li&gt;    &lt;li&gt;Use a loading page &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Action Item 1: Use a Splash Image&lt;/h4&gt;  &lt;p&gt;The first thing you can do is to help to solve the user experience issue. If the user sees an image of the application that says &amp;quot;Loading…&amp;quot;, he’ll wait a few more seconds before pressing the Back key out of frustration. Therefore, be smart and use a splash screen. &lt;/p&gt;  &lt;p&gt;In fact, all Windows Phone project templates include a splash screen image. By default, this image is named SplashScreenImage.jpg, and it automatically appears when your application is starting. The default image looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/arik/image_26F11585.png"&gt;&lt;img style="margin:0px auto;display:block;float:none;" title="image" alt="image" src="http://blogs.microsoft.co.il/blogs/arik/image_thumb_4C7A92E6.png" width="220" height="366" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Make sure to change the default image to something that suits the theme of your application. That way, when users see the splash screen (which happens instantly), they’ll recognize it as part of your application. Changing the default splash screen is also a Marketplace requirement.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Note&lt;/b&gt;: The image must have:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A size of &lt;b&gt;480 by 800&lt;/b&gt; pixels &lt;/li&gt;    &lt;li&gt;The filename set to &lt;b&gt;SplashScreenImage.jpg&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;The &lt;b&gt;Build Action&lt;/b&gt; set to &lt;b&gt;Content&lt;/b&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Action Item 2: Defer Work&lt;/h4&gt;  &lt;p&gt;This against everything your parents taught you, but when it comes to loading an application on Windows Phone, &lt;b&gt;never do now what you can do later&lt;/b&gt;. &lt;/p&gt;  &lt;p&gt;Postponing non-mission-critical work until after the application loads is always a good technique. At that point you aren’t constrained by time issues, and you might have time to run workload between user actions. &lt;/p&gt;  &lt;p&gt;For example, suppose you write a Sudoku game for Windows Phone. You might be tempted to generate the Sudoku game map when the application loads. However, it would be best to delay this action until the application is loaded and the user selects &amp;quot;New game.&amp;quot; At this point you can show some nice animation during the game setup process.&lt;/p&gt;  &lt;p&gt;You should defer any workload that isn’t critical to the application launch and doesn’t have a severe impact on the user experience when the application loads. Always prefer lazy initialization of objects, which promotes deferring non-essential workloads. &lt;/p&gt;  &lt;p&gt;Unfortunately, not every workload in your application launch sequence can be postponed. There are certain scenarios in which you can’t defer the workload to a later time in the application or until the user performs some operation. Some scenarios require you to run a workload as close as possible to the application start time. For example, consider an application that shows the top 10 trends currently on Twitter. Without the trends information, there’s nothing real to show on the application’s main page. However, we can&amp;#39;t afford for the application to be terminated just because it’s getting the latest trends over the network.&lt;/p&gt;  &lt;p&gt;To address scenarios in which your application has to complete some work close to startup time, you need to run some or all of the workloads in the background. This is exactly what we explain in the next section. &lt;/p&gt;  &lt;h4&gt;Action Item 3: Do Work on a Background Thread&lt;/h4&gt;  &lt;p&gt;This is probably the most important step in optimizing your application load time. To keep your application from hanging or terminating, the launch methods sequence must complete as soon as possible. If you can&amp;#39;t defer a certain workload, you have to run that work in the background, that is, on a background thread. &lt;/p&gt;  &lt;p&gt;You can use the following options:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;1. &lt;/b&gt;&lt;b&gt;Manually create a thread&lt;/b&gt;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e31278a6-c275-4af5-8343-e258e190dcf4" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt; thread = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;(() =&amp;gt; { &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.Init(); });&lt;br /&gt; thread.Start();&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;For additional information about manually creating threads, see the &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.thread(VS.95).aspx"&gt;Thread Class&lt;/a&gt; documentation.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;2. &lt;/b&gt;&lt;b&gt;Queue work item into the thread pool&lt;/b&gt;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f35a5346-c2ed-4567-a4a9-f364385c4ce0" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#2b91af;"&gt;ThreadPool&lt;/span&gt;.QueueUserWorkItem((o) =&amp;gt; { &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.Init(); });&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;For additional information about using the thread pool, see the &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool(VS.95).aspx"&gt;ThreadPool Class&lt;/a&gt; documentation. &lt;/p&gt;  &lt;p&gt;&lt;b&gt;3. &lt;/b&gt;&lt;b&gt;Use BackgroundWorker class&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;By using the BackgroundWorker class, you can assign a delegate that will perform the workload, as well as a callback method that will be executed once the delegate completes its operation. &lt;/p&gt;  &lt;p&gt;To use the &lt;b&gt;BackgroundWorker&lt;/b&gt; class, you’ll need to add a using statement for System.ComponentModel. &lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1760dab1-2903-4d56-92aa-51e8d464d6b0" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.ComponentModel;&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#2b91af;"&gt;BackgroundWorker&lt;/span&gt; backgroundWorker = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;BackgroundWorker&lt;/span&gt;(); &lt;br /&gt; &lt;br /&gt; backgroundWorker.DoWork += &lt;br /&gt;     (s,e) =&amp;gt; &lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#008000;"&gt;// runs on background thread&lt;/span&gt;&lt;br /&gt;         &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.Init(); &lt;br /&gt;     };&lt;br /&gt; &lt;br /&gt; backgroundWorker.RunWorkerCompleted +=&lt;br /&gt;     (s, e) =&amp;gt;&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#008000;"&gt;// runs on UI thread        &lt;/span&gt;&lt;br /&gt;     };&lt;br /&gt; &lt;br /&gt; backgroundWorker.RunWorkerAsync();&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;For additional information about using the BackgroundWorker class, see the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(VS.95).aspx"&gt;BackGroundWorker Class&lt;/a&gt; documentation &lt;/p&gt;  &lt;p&gt;When working with a background thread, you can’t directly update any UI control without marshaling to the UI thread from your back-thread. Silverlight offers a simple mechanism to do that by using the &lt;b&gt;Dispatcher.BegineInvoke&lt;/b&gt; method.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e7a75149-8181-4b39-ab41-b5585770d91b" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#2b91af;"&gt;Deployment&lt;/span&gt;.Current.Dispatcher.BeginInvoke(() =&amp;gt;&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#008000;"&gt;//This happens on UI thread, if you want to marshal info back to UI thread from any other background thread.&lt;/span&gt;&lt;br /&gt; });&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&lt;b&gt;&lt;i&gt;Note:&lt;/i&gt;&lt;/b&gt;&lt;i&gt; When working with background threads, you should always remember that UI components in Silverlight have thread affinity; that is, you can access a control only from the thread that created the control. So if you need to update the UI with progress/completed reports from the background thread, you should dispatch your code to run on the correct thread. This can be done by using the method &lt;b&gt;myControl.Dispatcher.BeginInvoke()&lt;/b&gt;, where myControl is the control you want to update.&lt;/i&gt;&lt;/p&gt;  &lt;h4&gt;Action Item 4: Use a Loading Page&lt;/h4&gt;  &lt;p&gt;Now that you’ve moved some of the workload to the background, your application will load much faster and you should see your application’s first page rather quickly. However, most likely you’ve got nothing meaningful (such as the new data you’re fetching) to show, since the background thread is still executing. Therefore, If you started some work on a background thread , you should consider showing a busy/loading indicator, like a progress bar, during the wait time.&lt;/p&gt;  &lt;p&gt;You should avoid having a separate page for the loading indicator UI, since it would become part of the application’s page back stack. This would create a strange scenario in which pressing the Back button from the main page would return the user to the loading page rather than exiting the app. &lt;/p&gt;  &lt;p&gt;Instead, in your main page, add a grid that contains two controls: the “loading control” that will show loading information (indicator), and the actual main page content. Toggle the &lt;b&gt;Visibility&lt;/b&gt; property of the two controls according to the current loading state. Also, if you set the ProgressBar’s IsIndeterminate property to true , &lt;i&gt;turn it off&lt;/i&gt; once you no longer need the loading screen, or you’ll have performance issues. You can read more about this at &lt;a href="http://blogs.microsoft.co.il/blogs/arik/archive/2011/01/27/a-progressbar-with-text-for-windows-phone-7.aspx"&gt;A ProgressBar With Text For Windows Phone 7&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;For example, the following XAML shows how a main page could be structured:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d345a698-f2c8-4572-940c-4667bf87714d" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; x&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;:&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;ContentPanel&amp;quot;&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Grid.Row&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Margin&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;12,0,12,0&amp;quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color:#a31515;"&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; x&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;:&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;loadingContent&amp;quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;         &lt;span style="color:#a31515;"&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;TextBlock&lt;/span&gt; &lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; HorizontalAlignment&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Center&amp;quot;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; VerticalAlignment&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Center&amp;quot;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; Margin&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;0,-30,0,0&amp;quot;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; Text&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Loading...&amp;quot;&lt;/span&gt; &lt;br /&gt;            &lt;span style="color:#0000ff;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;         &lt;span style="color:#a31515;"&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ProgressBar&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; x&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;:&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;progressBar&amp;quot;&lt;/span&gt; &lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; Minimum&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; Maximum&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;100&amp;quot;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color:#a31515;"&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color:#a31515;"&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; x&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;:&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Name&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;mainPageContent&amp;quot;&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Visibility&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Collapsed&amp;quot;&amp;gt;&lt;/span&gt;&lt;br /&gt;         &lt;span style="color:#a31515;"&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;TextBlock&lt;/span&gt; &lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; VerticalAlignment&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Center&amp;quot;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; HorizontalAlignment&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Center&amp;quot;&lt;/span&gt; &lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; FontSize&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;56&amp;quot;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#ff0000;"&gt; Text&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Main page data&amp;quot;&lt;/span&gt; &lt;br /&gt;            &lt;span style="color:#0000ff;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color:#a31515;"&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;The following code shows how to use the BackgroundWorker class to do the work in the background, update the progress bar, and toggle &lt;b&gt;Visibility&lt;/b&gt; when the work’s done:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9969a829-b671-4035-b249-97dd946a5fdf" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.BackgroundWorker = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;BackgroundWorker&lt;/span&gt;()&lt;br /&gt; {&lt;br /&gt;     WorkerReportsProgress = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;&lt;br /&gt; };&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.BackgroundWorker.DoWork +=&lt;br /&gt;     (s, e) =&amp;gt;&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.Init();&lt;br /&gt;     };&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.BackgroundWorker.ProgressChanged +=&lt;br /&gt;     (s, e) =&amp;gt;&lt;br /&gt;     {&lt;br /&gt;         progressBar.Value = e.ProgressPercentage;&lt;br /&gt;     };&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.BackgroundWorker.RunWorkerCompleted +=&lt;br /&gt;     (s, e) =&amp;gt;&lt;br /&gt;     {&lt;br /&gt;         loadingContent.Visibility = &lt;span style="color:#2b91af;"&gt;Visibility&lt;/span&gt;.Collapsed;&lt;br /&gt;         mainPageContent.Visibility = &lt;span style="color:#2b91af;"&gt;Visibility&lt;/span&gt;.Visible;&lt;br /&gt;     };&lt;br /&gt; &lt;br /&gt; &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;.BackgroundWorker.RunWorkerAsync();&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;In order to receive progress updates from the background thread, we passed the &lt;b&gt;BackgroundWorker&lt;/b&gt; to &lt;b&gt;MyService&lt;/b&gt; class, and use the &lt;b&gt;ReportProgress&lt;/b&gt; method:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5e8db11b-a39a-4b38-9c5c-600230ca85c7" class="wlWriterSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MyService&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; NumberOfIterations = 10;&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;BackgroundWorker&lt;/span&gt; BackgroundWorker { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt; &lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Init()&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; NumberOfIterations; ++i)&lt;br /&gt;         {&lt;br /&gt;             &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(1));&lt;br /&gt; &lt;br /&gt;             &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (BackgroundWorker != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;             {&lt;br /&gt;                 BackgroundWorker.ReportProgress((i+1) * 100 / NumberOfIterations);&lt;br /&gt;             }&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; &lt;br /&gt;     ...&lt;br /&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Another way to toggle between the controls is to bind the &lt;b&gt;Visibility&lt;/b&gt; property of both the &lt;b&gt;mainContent&lt;/b&gt; and &lt;b&gt;loadingContent &lt;/b&gt;to a Boolean flag that signifies the loading state (for example, bool isLoading). To do that, you’ll need a class that implements &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter(VS.95).aspx"&gt;IValueConverter&lt;/a&gt; to convert from bool to &lt;b&gt;Visibility&lt;/b&gt;.&lt;/p&gt;  &lt;h3&gt;Summary&lt;/h3&gt;  &lt;p&gt;Windows Phone applications must load fast and provide a good user experience. This is enforced by the application certification process and by the operating system. While the sample provided in this article is rather simple, the concepts remain true for all Windows Phone applications, and the techniques explained here will work for any Windows Phone application. &lt;/p&gt;  &lt;p&gt;Another important consideration is the actual versus the perceived user experience. There’s more than one way to show loading progress, other than a progress bar, but it’s important to show something that’s meaningful and tells the user,“Hey, soon you’ll see your favorite app.” &lt;/p&gt;  &lt;p&gt;That’s it for now,    &lt;br /&gt;Arik Poznanski.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/03/25/ways-to-load-applications-faster-a-windows-phone-recipe.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/03/25/ways-to-load-applications-faster-a-windows-phone-recipe.aspx&amp;amp;bgcolor=6600FF" /&gt;&lt;/a&gt; &lt;a href="http://dotnetshoutout.com/Submit?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/03/25/ways-to-load-applications-faster-a-windows-phone-recipe.aspx"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http://blogs.microsoft.co.il/blogs/arik/archive/2011/03/25/ways-to-load-applications-faster-a-windows-phone-recipe.aspx" style="border:0px;" /&gt;&lt;/a&gt; &lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=172641" rel="tag" style="display:none;"&gt;CodeProject&lt;/a&gt; &lt;/div&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=813930" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/DEV/default.aspx">DEV</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Windows+Phone+7/default.aspx">Windows Phone 7</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Threads/default.aspx">Threads</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Application+Loading/default.aspx">Application Loading</category><category domain="http://blogs.microsoft.co.il/blogs/arik/archive/tags/Recipe/default.aspx">Recipe</category></item></channel></rss>