Sunday, January 8, 2012

Windows Azure Storage Table Names

While writing a unit test for a class that created a Windows Azure Storage table, I named the test table “Test_Function_Date” where Function and Date where replaced with meaningful test information. The underscores in the table name were also there.

 

Azure CloudTableClient.CreateTableIfNotExist Exception

While running the test, my call to CloudTableClient.CreateTableIfNotExist(TableName) threw an exception.

 

image

 

Illegal Table Name Exception Details

The outer exception is Exception of type 'Microsoft.WindowsAzure.StorageClient.StorageClientException' was thrown. The inner exception is "An error occurred while processing this request." Buried in the inner exception XML is a status code of OutOfRangeInput, with a message of “One of the request inputs is out of range.” Since this was a single unit test with not much prep work, I figured out it was the table name.

 

Azure Table Name Rules

The rules for table naming allow:

  • alphanumerics
  • do not begin with a numeric
  • case insensitive
  • length from 3 to 63

Regular Expression for Azure Table Name Rules

The regular expression (provided by Neil Mackenzie) is:

 

^[A-Za-z][A-Za-z0-9]{2,62}$

So in the example table name of “Test_Function_Date”, the underscores were the problem.

Sunday, January 1, 2012

Code Faster Review and Favorite Tips

This review covers “Coding Faster: Getting More Productive with Microsoft Visual Studio: Covers Microsoft Visual Studio 2005, 2008, and 2010” by Zain Naboulsi and Sara Ford.

 

Why I Ordered the Book

I ordered this book with the hopes of getting some quick and easy speed improvements to my coding style. If you are looking for just such a shortcut key primer, the poster address for all languages is available.  [Alternative link to posters] This book covers a bit more and takes a little more time to digest. That’s not bad.

 

Who should Buy this Book

As a huge, feature-rich product with numerous versions, mastering Visual Studio is a challenge in itself. I must admit I tend to focus more on the language and SDKs of the current project, and less on the IDE. Sitting down with the book gave me time to correct that. If you have any desire to master your Visual Studio coding environment, buy this book.

 

Book Layout

The book is organized with seven chapters:

1. Getting Started

2. Projects and Items

3. Getting to Know the Environment

4. Working with Documents

5. Finding Things

6. Writing Code

7. Debugging

 

There is a bonus at the back of the book covering extensions found at the Visual Studio Gallery.

 

Favorite Tips

 

There were plenty of gems for speed improvement in there. Here are a few of my favorites:

  • 02.14 Roll Your Own Project Template with the Export Template Wizard Alt+F, E
  • 03.03 Cycle through Your Open Tool Windows Alt+F6
  • 06.02 Zoom In & Out of Text in Editor Ctrl+Shift+Mouse Wheel
  • 06.04 Make IntelliSense Transparent Press and hold Ctrl
  • 06.15 Select everything in the braces Ctrl+Shift+}
  • 07.08 Code Definition Window Ctrl+\,D

Favorite Extension

There are plenty of spelling extensions but oddly developers don’t general look for or install them. Here is a free extension that will correct your spelling. If you generate API documentation from code files, you must have a spell checker.

Monday, December 26, 2011

Unit Test Initialization and Cleanup for Windows Azure Storage Emulator

My unit tests add and delete entities from local Windows Azure dev storage,  at their most basic. If the Azure Storage emulator isn’t started, the tests don’t fail quickly – they just sit there acting like the test framework is hung. In order to ensure that the tests proceed, I needed to make sure the emulator was started before the tests ran.

 

I started with code found in this thread on StackOverflow. I needed to make sure the Storage Emulator is started before the test classes are called and that the emulator is shut down when the tests are done. I wrote this class and added it as a separate file to my test assembly.

 

More information about CSRun.exe and the Process class are available in MSDN.

 

// -----------------------------------------------------------------------
// <copyright file="AssemblySpecific.cs" company="BerryIntl">
// Berry International 2011
// </copyright>
// -----------------------------------------------------------------------

namespace Wp7AzureMgmt.Dashboard.Test
{
    using System;
    using System.Text;
    using System.Collections.Generic;
    using System.Linq;
    using System.Diagnostics;
    using System.IO;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Class containing assembly specific test initialization and cleanup
    /// </summary>
    [TestClass]
    public class AssemblySpecific
    {
        /// <summary>
        /// Location of csrun.exe - may be different base on install point and azure sdk version
        /// </summary>
        private const string AzureSDKBin = @"C:\Program Files\Windows Azure Emulator\emulator";

        /// <summary>
        /// Code to run before ClassInitialize or TestInitialize
        /// </summary>
        /// <param name="context">TestContext context</param>
        [AssemblyInitialize]
        public static void MyAssemblyInitialize(TestContext context)
        {
            List<Process> processStatus = Process.GetProcessesByName("DSService.exe").ToList();

            if (( processStatus == null ) || ( processStatus.Count == 0 ))
            {
                ProcessStartInfo processStartInfo = new ProcessStartInfo()
                {
                    FileName = Path.Combine(AzureSDKBin, "csrun.exe"),
                    Arguments = "/devstore",
                };
                using (Process process = Process.Start(processStartInfo))
                {
                    process.WaitForExit();
                }
            }
        }

        /// <summary>
        /// Code to run before ClassCleanup or TestCleanup
        /// </summary>
        [AssemblyCleanup]
        public static void MyAssemblyInitialize()
        {
            List<Process> processStatus = Process.GetProcessesByName("DSService.exe").ToList();

            if ((processStatus != null) || (processStatus.Count > 0))
            {
                ProcessStartInfo processStartInfo = new ProcessStartInfo()
                {
                    FileName = Path.Combine(AzureSDKBin, "csrun.exe"),
                    Arguments = "/devstore:shutdown",
                };
                using (Process process = Process.Start(processStartInfo))
                {
                    process.WaitForExit();
                }
            }
        }
    }
}

Thursday, December 8, 2011

Simple Azure Web and Worker Roles–Running the code

This is a continuation of the simple series. Links for other posts in the series are at the bottom of this post. Download Visual Studio Solution here.

 

This series explains the Windows Phone 7 requesting data from a Windows Azure web service. The phone tile and toast are supported by a background agent on the phone while the web service is supported by a continuous worker role on Windows Azure.

Document 1

The phone calls the WebRole REST API from both the phone app and the phone app’s background agent. Each request is different though. The App’s request is fetching a list of items to show in the app while the background agent is fetching the count of items since the last fetch and the very last item. This information will be displayed in the popup toast and the app’s start screen pinned tile.

 

Azure Only

This post will cover the Azure web  and worker roles only. The Windows Phone 7 app-to-Azure communication will be covered in a separate post. Grab the Visual Studio solution available for download. Running the project doesn’t require that you have an Azure account but you will need the Azure SDK installed.

 

Prerequisites

In order to make this simple sample work, you need to have the following installed:

  • Visual Studio (not Express)
  • Azure SDK 1.4

The AzureSample Solution

The Azure Visual Studio solution has several projects:

 

image

 

The Solution Items project contains a text file of blog post URLs that I found helpful. The Azure project is where the Azure configuration settings are stored. Since this sample enters data into Azure Storage tables, you will notice that the Azure project ServiceConfiguration.Local.cscfg file uses local developer storage.

<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="1" osVersion="*">
  <Role name="MvcWebRole">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
    </ConfigurationSettings>
  </Role>
  <Role name="WorkerRole">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

The next project in the AzureSample Solution is the AzureSharedLibrary which is where the main code for the solution is shared between the Web Role and the Worker Role projects. The MvcWebRole project contains both the REST API answering the phone’s requests as well as an HTML page that refreshes to display the top 100 chronological rows in Azure Storage. The last project is the WorkerRole which periodically cycles to enter data into the table.

 

Both the MvcWebRole and the WorkerRole have as little code in them as possible. I did this on purpose so that you could see what I added and how it pulled together from the shared library.

 

What does the Sample Do?

If you let the sample run, you will see the web page refreshes with new data every few seconds. Both the web page (in the web role) and the worker role are inserting information into the Azure Storage table. Granted this isn’t the typical scenario, it is just an example. In a future post, I’ll connect a Windows Phone 7 app and background agent to this AzureSample and they will all work together.

In my current development project, the worker role is polling a 3rd party web site for new information and inserting the information into the Azure Storage table. Then the phone app is requesting that new information either through the phone’s app or background process.

 

Running the Code

Start Visual Studio with elevated permissions: right click on the VS program and select Run as Administrator.

image

 

Make sure the Azure project is set as the start project then start to debug. The Azure emulators should start if they weren’t already. The default web page should display revealing the data inserted by both roles.

 

Viewing the Data

Once the solution is started, the web page for the MvcWebRole will display. After a few seconds of running, it should show some lines of data that include the process name and the UTC date it was entered.

 

image

 

Even though the local storage emulator is used, you can view the data via the Visual Studio server explorer or a third party tool such as Azure Storage Explorer. Both work with the local storage emulator.

 

Visual Studio Server Explorer

image

 

Azure Storage Explorer

image

 

 

Summary

This blog post showed how to allow a web and worker role to access the same Azure Storage table. The web role provides both web page and REST access to the data while the worker role only inserts the data into the table. In the next post, I’ll go through the code for these two roles.

 

Simple Series

Tuesday, November 15, 2011

Simple WP7 Mango App for Background Tasks, Toast, and Tiles: Code Explanation

This is a continuation of this post, explaining how the sample app works.

image

Caution: This sample isn’t meant as an example of best patterns and practices. If you see something in the code you would never do, then don’t.

Solution File Organization

The app has three Visual Studio Projects: the app, the agent, and the shared code library between them.

clip_image001

One of the great things about Mango is that now the built-in Visual Studio Unit test functionality is available. By separating out the meat of the work into the SampleShared project, I can also focus my unit testing there.

SampleApp1

The app has a MainPage, a ViewModel, and the WMAppManifest.xml file modified to note my ExtendedTask of BackgroundServiceAgent.

clip_image002

The Agent is extremely simple with a call to the shared library, an update to the Tile, and a call to pop up Toast.

clip_image003

The meat of the work is in the SampleShared library.

clip_image004

The AgentMgr manages the background agent: add, remove, find, run now. It is only called from the app via these buttons:
· Start Agent,
· Stop Agent,
· Launch For Test.

The BackgroundAgentRESTCall is a containing class for all the true processing I want the agent to do. It is only called from the agent. For this sample app, it just reads and writes to the mutexed isolated storage file.

The FileIsoStorageMutex class is called by both the agent and the app via these buttons:
· Read ISO Storage,
· Write ISO Storage.

The best practices suggests mutex-protected storage:
"For one-direction communication where the foreground application writes and the agent only reads, we recommend using an isolated storage file with a Mutex. We recommend that you do not use IsolatedStorageSettings to communicate between processes because it is possible for the data to become corrupt."

TileNotification updates the app tile pinned to the start screen via the Update Tile button. It is also called by the agent. By putting the tile code in a separate assembly, I avoid the issue that I can’t update the tile from the UI thread. The toast notification is called by the agent.

Debug Tip: Use the Debug.WriteLine() liberally and keep an eye on the Output window. This is where you can see the background agent begin and end.

Dive into Code - App

The three main parts of the code for the app are the MainPage, the ViewModel, and the WMAppManifest. The MainPage uses the ViewModel which in turn calls over to the SampleShared library. The WMAppManifest, however, has a new section and the Visual Studio project creation for the app didn’t add it – you get to do that.

The tasks section and default task were already there. I added the extended task:
<Tasks>
      <DefaultTask  Name ="_default" NavigationPage="MainPage.xaml"/>
      <ExtendedTask Name="BgTask">
        <BackgroundServiceAgent Specifier="ScheduledTaskAgent"
                                Name="Sample Agent" Source="SampleAgent"
                                Type="SampleAgent.SampleAgent" />
      </ExtendedTask>
    </Tasks>
The TextFile1.txt file of the App project includes all the blog posts and web pages I read to research this topic. If you want other code examples, explanations, or related Microsoft MSDN library documentation, use the links found there.

 

Dive into Code - The Agent Code

The agent code may be new to you but my example is short and simple. The default OnInvoke() provided when I created the Visual Studio Background Agent project is the only code in that project.

public class SampleAgent : ScheduledTaskAgent
    {

        public String BackgroundPNG = "background.png";
        public String MainPageURLForToast = "/MainPage.xaml";
        public String ToastTitle = "Mutex:";
        
        /// <summary>
        /// Called by the system when there is work to be done
        /// </summary>
        /// <param name="Task">The task representing the work to be done</param>
        protected override void OnInvoke(ScheduledTask Task)
        {
            Debug.WriteLine("SampleAgent.SampleAgent.OnInvoke");

            //Here is where you put the meat of the work to be done by the agent
            IsoStorageData MutexedData = BackgroundAgentRESTCall.Call();

            //Toast Popups (processname + datetime in minutes)
            ToastNotifications.ShowToast(ToastTitle, MutexedData.LastProcessToTouchFile + "-" + MutexedData.LastTimeFileTouched.ToShortTimeString().ToString(), MainPageURLForToast);

            //Tile Pinned to Start screen (processname + datetime in minutes)
            // "2" signifies sampleagent
            TileNotifications.UpdateTile(MutexedData.LastProcessToTouchFile + "-" + MutexedData.LastTimeFileTouched.ToShortTimeString().ToString(), BackgroundPNG, 2);

            // this makes the agent run in a shorter cycle than 30 minutes
            // if the iso data setting is turned off (from the app)
            if (MutexedData.CycleAgentEveryMinute)
            {
                AgentMgr.RunDebugAgent();
            }

            //Required Background Agent Finisher
            NotifyComplete();
      }

    }

Shared Code library

The real work is in this file so I’m going to go through the four areas: isolated storage, toast, tiles, and agent. This is a great place to put code to grab data from the phone app which the agent doesn’t have access to. There are many unsupported APIs that the background agents can’t use.

Dive into Code - Shared Code - FileIsoStorageMutex.cs

FileIsoStorageMutex is the class that allows the app and agent to read and or write to the same isolated storage, effectively sharing data. Since the agent and app can wind up using the storage at the same time, I protect the file by a named mutex.

private static Mutex Mutex = new Mutex(false, "BackgroundAgentDemo1");


In order to create a mutex, you have to add a using statement of System.Threading which is contained in the mscorlib.Extensions.dll. Add the dll to the references section of the shared project.

In a production app, I would separate out the data. One isolated storage file would contain app-only data and a second, mutexed file would contain the data that is shared between the app and the agent. While I’m sure the mutex will protect the file sufficiently, I wouldn’t want to accidentally overwrite critical app data which might require a round-trip back to the server or input from the customer.

The code has two functions: read and write. Nothing tricky in either.
// Data object serialized to isolated storage
    public class IsoStorageData
    {
        //datetime of last write to iso storage
        public DateTime LastTimeFileTouched {get;set;}

        //app or agent
        public String LastProcessToTouchFile { get; set; }

        //true==continuous (every minute) cycle of agent
        public bool CycleAgentEveryMinute { get; set; }
    }

    // iso storage manager
    public static class MutexedIsoStorageFile
    {
        //named mutex
        private static Mutex Mutex = new Mutex(false, "BackgroundAgentDemo1");

        //name of isolated storage file
        private const String IsoStorageDateFile = "BackgroundAgentDemo1data.txt";

        //read iso storage
        //debug.writeline lets me "see" agent working in VS output window
        public static IsoStorageData Read()
        {
            IsoStorageData IsoStorageData = new IsoStorageData();

            Mutex.WaitOne();

            try
            {
                using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                using (var stream = new IsolatedStorageFileStream(IsoStorageDateFile, FileMode.OpenOrCreate, FileAccess.Read, store))
                using (var reader = new StreamReader(stream))
                {
                    if (!reader.EndOfStream)
                    {
                        var serializer = new XmlSerializer(typeof(IsoStorageData));
                        IsoStorageData = (IsoStorageData)serializer.Deserialize(reader);
                    }
                }
            }
            finally
            {
                Mutex.ReleaseMutex();
            }
            Debug.WriteLine("RRR-data.LastProcessToTouchFile=" + IsoStorageData.LastProcessToTouchFile);
            Debug.WriteLine("RRR-data.LastTimeFileTouched=" + IsoStorageData.LastTimeFileTouched.ToString());
            Debug.WriteLine("RRR-data.CycleAgentEveryMinute=" + IsoStorageData.CycleAgentEveryMinute.ToString()); 
           
            return IsoStorageData;
        }
        //write iso storage
        //debug.writeline lets me "see" agent working in VS output window
        public static void Write(IsoStorageData data)
        {
            Debug.WriteLine("WWW-data.LastProcessToTouchFile=" + data.LastProcessToTouchFile);
            Debug.WriteLine("WWW-data.LastTimeFileTouched=" + data.LastTimeFileTouched.ToString());
            Debug.WriteLine("WWW-data.CycleAgentEveryMinute=" + data.CycleAgentEveryMinute.ToString());

            // persist the data using isolated storage
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            using (var stream = new IsolatedStorageFileStream(IsoStorageDateFile,
                                                              FileMode.Create,
                                                              FileAccess.Write,
                                                              store))
            {
                var serializer = new XmlSerializer(typeof(IsoStorageData));
                serializer.Serialize(stream, data);
            }
        }

    }

Dive into Code - Shared Code - Tile Notifications

The default tile that is created as part of the app is used by this application. In a production app, I wouldn’t touch the tile from the app, opting instead to either use in-app notifications similar to the top, numeric indicator in the Facebook app or I would depend on the agent to alter the tile in the next 30 minute window. However, this is a sample so the app is directly updating the tile.
public static class TileNotifications
    {
        //update existing tile
        //no secondary tile
        //no animation
        //Title is title displayed on tile
        //background is can be changed but I use default image
        //good example of changed background image is the People Hub tile
        //count is the number to show in the little black circle
        public static void UpdateTile(String title, String backgroundImageUri, int count)
        {
            ShellTile firstTile = ShellTile.ActiveTiles.First();
            var newData = new StandardTileData() 
            { 
                Title = title, 
                BackgroundImage = new Uri(backgroundImageUri, UriKind.Relative),
                Count = count, 
            };

            firstTile.Update(newData);
        }
    }

The code doesn’t add more tiles, it doesn’t do anything with the backside of the tile, and it doesn’t have animations.

Dive into Code - Shared Code - Toast Notifications

Toast is only popped up via the agent but I wanted it in the shared app project so that I could have a single project for unit testing. The default Visual Studio Unit Test functionality is available to use in Mango while it wasn’t in Metro.
public static class ToastNotifications
    {
        //pop up toast
        //Title is the first part of the string - app name or reference key word
        //signifying app
        //Content is the second part of the string
        //Title + Content is how it is displayed
        //NavigationUri is the page inside your app that you want
        //the user taken to when they select/touch/click on your toast pop up
        //it doesn't have to be the main page
        public static void ShowToast(String title, String message, String NavigationURL)
        {
            var toast = new ShellToast
            {
                Title = title,
                Content = message,
                NavigationUri = new System.Uri(NavigationURL, System.UriKind.Relative)
            }; 
            
            toast.Show();
        }
    }


Dive into Code - Shared Code - BackgroundAgentRESTCall

The last class file contains the code that the agent calls to do the work. The code isn’t shared with the app in this sample, but in a production app I would have a single call that deals with notifications which the app and agent would share.
public static class BackgroundAgentRESTCall
    {
        public const String ProcessName = "Agent";

        public static IsoStorageData Call()
        {
            //This is where you put the call to your webservice. This
            //call can/should determine what to display on the tile and/or
            //toast. However, bring back as little as possible. Leave 
            //the bigger capture of data to your app.
 
            //For purposes of this sample, we just write/read iso storage 
            //and return results

            //Read the mutexed iso storage to get mutexedData.CycleAgentEveryMinute 
            IsoStorageData mutexedData = MutexedIsoStorageFile.Read();

            //Current datetime
            DateTime DateTimeNow = DateTime.Now;

            //Put current process and datetime into mutexed iso storage 
            //carry over previous cycle value
            MutexedIsoStorageFile.Write(new IsoStorageData()
            {
                LastProcessToTouchFile = ProcessName,
                LastTimeFileTouched = DateTimeNow,
                CycleAgentEveryMinute = mutexedData.CycleAgentEveryMinute 
            });

            //Read the mutexed iso storage to verify it was written
            mutexedData = MutexedIsoStorageFile.Read();

            return mutexedData;
        }
    }

Summary

This sample showed a simple app using a background agent to update the pinned tile and pop up toast. The .XAP binary and code solution are both available for download.   

Monday, November 14, 2011

A Simple WP7 Mango App for Background Tasks, Toast, and Tiles

Download Binary and Code

The .XAP binary and code solution are both available for download. The app uses a background process that does some work then updates the tile and pops up toast. The app and the agent talk to each other via an isolated storage file protected by a named mutex. The diagram below shows the pieces and how they work together.

This is the app associated with this post.

App/Agent Architecture


clip_image001

The app and agent don’t actually talk to a web service as this is a sample but in a real world solution they both would. The app would do the heavy lifting. The agent would have a quick, light conversation with just enough information to update the tile and pop up toast with meaningful information.

In this sample, you can configure the agent to run repetitively every minute, second, etc. This is usually done for debug/testing. In the usual release situation, the agent runs on the 30 minute cycle.

Start the App

clip_image006

Pin the App to the Start Screen

Make sure to the pin the app to the start screen as that is where the toast and tile changes will appear. Notice no toast or tile changes yet.
clip_image007

Write Iso Storage

To begin, select the “Write Iso Storage” button, which sets the iso storage to have the name of the process that touched it (“App”) and the datetime the storage was written to. You can verify the iso storage data by looking at the UI which reads from the iso storage after the write.

In this sample, I also write to the output windows to show this. This information in the output window helps me keep track of when and who wrote to isolated storage. RRR means reading from storage. WWW means writing to storage.


RRR-data.LastProcessToTouchFile=
RRR-data.LastTimeFileTouched=1/1/0001 12:00:00 AM
RRR-data.CycleAgentEveryMinute=False
WWW-data.LastProcessToTouchFile=App
WWW-data.LastTimeFileTouched=11/14/2011 8:52:23 AM
WWW-data.CycleAgentEveryMinute=False


Update Tile

Let’s update the app tile to show the iso storage data by selecting the “Update Tile” button then select the phone’s start button to go to the start screen and verify the tile has been updated with “App” and a time. The count in the circle at the top of the tile should be 1. It’s an arbitrary number for this sample. “1” is another signifier meaning the app set the tile. “2” means the agent set the tile.
clip_image008

Verify Settings | Applications | Background tasks

Let’s verify that, while the app is running, the background process for this app has not been turned on yet. Select the start button and go to settings| applications | background tasks. The app of “SampleApp1” should not be in the list.

clip_image009

Go back to App

Now, hold down the back button and select the sample app.

clip_image010
So far, the app touched mutexed isolated storage and the tile. The agent hasn’t been started.

Start Agent

The next thing we can do is select the “Start Agent” button. The background agent does three things: 1) updates the iso storage, 2) pops up toast, and 3) updates the existing tile. Notice the app UI hasn’t changed. If you select the “Read Iso Storage” button, you still see no changes.

And a final place to look, notice that the output windows doesn’t show any work from the background agent. The point is that starting the background agent didn’t do any obvious work. Let’s verify the code did something. Go back to settings | application | background tasks.

clip_image011

Great! The app is now in the background task list so it is “on” but hasn’t run yet. By default, this app uses the standard 30 minute cycle for the agent. But we don’t have to wait that long. Go back to the app.

Launch For Test

Select the “Launch For Test” button and then pop back out to the phone’s start screen. Also make sure you can see the output window of Visual Studio. You may have to wait a few seconds to a minute or more, depending on what your phone is doing at the time.

The start screen showed a change to the tile as well as toast popped up.
clip_image012

The output window showed the Agent’s OnInvoke() call, as well as exiting the code at the end.

SampleAgent.SampleAgent.OnInvoke
RRR-data.LastProcessToTouchFile=Agent
RRR-data.LastTimeFileTouched=11/14/2011 9:07:38 AM
RRR-data.CycleAgentEveryMinute=False
WWW-data.LastProcessToTouchFile=Agent
WWW-data.LastTimeFileTouched=11/14/2011 9:09:34 AM
WWW-data.CycleAgentEveryMinute=False
RRR-data.LastProcessToTouchFile=Agent
RRR-data.LastTimeFileTouched=11/14/2011 9:09:34 AM
RRR-data.CycleAgentEveryMinute=False
The thread '<No Name>' (0xe12012a) has exited with code 0 (0x0).
The thread '<No Name>' (0xe270136) has exited with code 0 (0x0).
The thread '<No Name>' (0xfb30142) has exited with code 0 (0x0).
The program '[253296902] Background Task: Managed' has exited with code 0 (0x0).

If you continue waiting, nothing more will happen as the launch was a one-time event. However, we can change that.

Continuous 1min Cycle of Agent

Move back to the app. The text info at the top of the UI should show the same thing the start screen tile and output window showed.

clip_image013

When the agent is started, it is on a 30 minute cycle. When we launch for test, we run the agent once immediately. But if we want the agent to run repeatedly, we need to configure the agent to do that. This sample app does that via the “Continuous 1min Cycle of Agent” checkbox.

Go ahead and check it. The checkbox writes to iso storage the new setting and the agent reads the setting. At the bottom of the OnInvoke() of the agent, the launch is repeated.

Continuous Cycling

The UI changes to say the app touched storage. Now select the “Launch For Test” button again to get the cycle started. Go back to the start screen. Keep an eye on the tile, toast, and Visual Studio output window. The tile and toast should update and the output window should report agent begin and ending. This cycle should repeat until you stop the uncheck the box, stop the agent, stop the debug session, or uninstall the app.

Caution: If you deployed or debugged on your physical phone, instead of the emulator, remember to stop the agent and delete the sample app when you are done. Otherwise, this can be an annoying app with the constant toast pop ups.

The Code

I’ll explain the code in the next blog post.

Wednesday, October 26, 2011

Windows Azure Cache Tip: Use language change to refresh cache

Several times using the Windows Azure Portal, the page has appeared to recycle correctly its 30 second refresh yet the process change I know reported success doesn’t show up. After a forum thread with a MS Support person, I learned to change the language setting at the top instead of log out and log in.

 

30 Second Refresh at the bottom left of the Browser Window

 

image

 

Change Language setting to refresh Portal Cache at the top right of the Browser Window

image