Town Of Cary Information Technology Board

 

Not much sharable code this week.  I did get appointed to the Town Of Cary’s Information Technology Board:

image

MCPD 4.0

I passed my last upgrade exam last week so I am now officially a MCPD 4.0.

MCPD(rgb)_1372_1371

Windows Phone 7– Duh Moment Of The Day

So I wrote this code block in a Windows Phone 7 application:

1 private void CreateNewLogFile() 2 { 3 string logFileLocation = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); 4 if (File.Exists(logFileLocation)) 5 File.Delete(logFileLocation); 6 7 } 8

And I got this exception:

image

And it hit me – can’t write to the local file system of the emulator using Windows Desktop/Server constructs. To write in a Windows Phone 7 application, I need to write to the local storage.  However, since I can’t read from local storage easily (no WindowsExplorer access) – I would need to write a program to get the data out.  This seems more trouble than it is worth.  I’ll just write to the Debug window….

Windows Phone 7–Threading Issues With the Stopwatch Class

I am writing a profiling application to help me with some performance problems that I am having with the Windows Phone 7 game I am writing.  Here is a snippet where I track the time it takes to load in the game data for a given scenario:

1 private void LoadTile() 2 { 3 Stopwatch stopWatch = new Stopwatch(); 4 ScenarioTileFactory scenarioTileFactory = new ScenarioTileFactory(); 5 List<ScenarioTile> scenarioTiles = null; 6 stopWatch.Start(); 7 scenarioTiles = scenarioTileFactory.GetScenarioTiles(20); 8 stopWatch.Stop(); 9 this.TilesListBox.Items.Add(String.Format("Scenario {0} has {1} tiles and it took {2}.", 10 "20", scenarioTiles.Count.ToString(), stopWatch.ElapsedMilliseconds.ToString())); 11 12 } 13

When I run it, I get this (which is correct):

image

I then wanted time how long each scenario takes to load and update the UI after each load.  I immediately thought of using a second thread – 1 to load the data and the main UI thread to update the screen.  I update my load function for multi-threading like so:

1 Stopwatch stopWatch = new Stopwatch(); 2 ScenarioTileFactory scenarioTileFactory = new ScenarioTileFactory(); 3 List<ScenarioTile> scenarioTiles = null; 4 stopWatch.Start(); 5 scenarioTiles = scenarioTileFactory.GetScenarioTiles(20); 6 stopWatch.Stop(); 7 this.TilesListBox.Dispatcher.BeginInvoke(() => 8 { 9 this.TilesListBox.Items.Add(String.Format("Scenario {0} has {1} tiles and it took {2}.", 10 "20", scenarioTiles.Count.ToString(), stopWatch.ElapsedMilliseconds.ToString())); 11 }); 12 stopWatch.Reset(); 13 stopWatch.Start(); 14 scenarioTiles = scenarioTileFactory.GetScenarioTiles(21); 15 stopWatch.Stop(); 16 this.TilesListBox.Dispatcher.BeginInvoke(() => 17 { 18 this.TilesListBox.Items.Add(String.Format("Scenario {0} has {1} tiles and it took {2}.", 19 "21", scenarioTiles.Count.ToString(), stopWatch.ElapsedMilliseconds.ToString())); 20 }); 21

The results started getting screwy:

image

 

It sure looks like the Stopwatch.Reset is not thread-aware? Nope, hoping the thread back calls an auto refresh. For example, I put a break:

image

 

But when I hop the thread and go back to the UI thread:

image

So the stopwatch class is not thread-safe. Good to know! To get around this problem, I created a local holding variable and passed that value over to the UI thread:

1 private void LoadTiles() 2 { 3 Stopwatch stopWatch = new Stopwatch(); 4 ScenarioTileFactory scenarioTileFactory = new ScenarioTileFactory(); 5 List<ScenarioTile> scenarioTiles = null; 6 long elapsedTime = 0; 7 for (int i = 0; i < 30; i++) 8 { 9 stopWatch.Reset(); 10 stopWatch.Start(); 11 scenarioTiles = scenarioTileFactory.GetScenarioTiles(i); 12 stopWatch.Stop(); 13 elapsedTime = stopWatch.ElapsedMilliseconds; 14 15 this.TilesListBox.Dispatcher.BeginInvoke(() => 16 { 17 this.TilesListBox.Items.Add(String.Format("Scenario {0} has {1} tiles and it took {2}.", 18 i.ToString(), scenarioTiles.Count.ToString(), elapsedTime.ToString())); 19 }); 20 } 21 } 22

 

Now I have accurate diagnostic information for my analysis:

 

image

RDU Code Camp Material

All of the material that I presented last Saturday at Trinug’s code camp is available here.

The Daily WTF

I took a break from coding for the RDU Code Camp and went over to the daily WTF. This is a great WTF that I decided to dig into.

I created a project and added in an enum with the following signature:

1 public enum ApplicationTypeEnum 2 { 3 Stradegy2, 4 AdDetector, 5 MagAdvisor, 6 AdDetectorAlerts, 7 MarketAdvisorAdTel, 8 NewspaperAdvisor, 9 MarketAdvisorMarketSpender, 10 StradegyOnline, 11 AdSpender, 12 Evaliant, 13 eBooks, 14 FrenchAdex 15 } 16

I then added an Application Class and copy/pasted in the method that was in the post:

1 public class Application 2 { 3 private int SetApplicationId() 4 { 5 switch (ApplicationUserInfo.Current.ApplicationType.ToString()) 6 { 7 case "Stradegy2": return Convert.ToInt32(ApplicationTypeEnum.Stradegy2); 8 case "AdDetector": return Convert.ToInt32(ApplicationTypeEnum.AdDetector); 9 case "MagAdvisor": return Convert.ToInt32(ApplicationTypeEnum.MagAdvisor); 10 case "AdDetectorAlerts": return Convert.ToInt32(ApplicationTypeEnum.AdDetectorAlerts); 11 case "MarketAdvisorAdTel": return Convert.ToInt32(ApplicationTypeEnum.MarketAdvisorAdTel); 12 case "NewspaperAdvisor": return Convert.ToInt32(ApplicationTypeEnum.NewspaperAdvisor); 13 case "MarketAdvisorMarketSpender": return Convert.ToInt32(ApplicationTypeEnum.MarketAdvisorMarketSpender); 14 case "StradegyOnline": return Convert.ToInt32(ApplicationTypeEnum.StradegyOnline); 15 case "AdSpender": return Convert.ToInt32(ApplicationTypeEnum.AdSpender); 16 case "Evaliant": return Convert.ToInt32(ApplicationTypeEnum.Evaliant); 17 case "eBooks": return Convert.ToInt32(ApplicationTypeEnum.eBooks); 18 case "FrenchAdex": return Convert.ToInt32(ApplicationTypeEnum.FrenchAdex); 19 20 } 21 return 0; 22 } 23 } 24

I then had to tackle this line of code to get the app to compile:

1 switch (ApplicationUserInfo.Current.ApplicationType.ToString())

I created a ApplicationUserInfo class like so:

 

1 public class ApplicationUserInfo 2 { 3 public Current Current { get; set; } 4 } 5

And then a Current class like so:

1 public class Current 2 { 3 public ApplicationTypeEnum ApplicationType { get; set; } 4 } 5

Since properties can’t be static in C#, I needed to create an instance of the ApplicationUserInfo class in the Application class via a property:

1 public ApplicationUserInfo ApplicationUserInfo { get; set; }

I changed the scope of the SetApplicationId method to public and was then ready to throw a couple of unit tests on this:

1 [TestMethod()] 2 public void SetApplicationId_SetStradgy2ToApplicationUserInfo_Returns0_Passes_Test() 3 { 4 Application application = new Application(); 5 application.ApplicationUserInfo = new ApplicationUserInfo(); 6 application.ApplicationUserInfo.Current = new Current(); 7 application.ApplicationUserInfo.Current.ApplicationType = ApplicationTypeEnum.Stradegy2; 8 int expected = 0; 9 int actual = application.SetApplicationId(); 10 Assert.AreEqual(expected, actual); 11 } 12 13 [TestMethod()] 14 public void SetApplicationId_DoNotSetApplicationUserInfo_Returns0_Passes_Test() 15 { 16 Application application = new Application(); 17 application.ApplicationUserInfo = new ApplicationUserInfo(); 18 application.ApplicationUserInfo.Current = new Current(); 19 int expected = 0; 20 int actual = application.SetApplicationId(); 21 Assert.AreEqual(expected, actual); 22 } 23

The tests point out 2 WTFS immediately. The classes depend on an external variable that may or may not be instantiated. There is no argument validation. Also, note how 0 is a return value for “Stradegy2” and “None provided”. If “Stradegy2” is supposed to be the default value, it would be put into the “defult” section of the switch…case. Oh wait, no default – WTF #3.

Finally, SetApplicationId can be cleaned up with this nugget:

1 public int SetApplicationId() 2 { 3 return Convert.ToInt32(ApplicationUserInfo.Current.ApplicationType); 4 } 5

If you read the comments of the question, this was suggested in various forms (some even with the right syntax). WTF #4.