Thursday, January 15, 2009

[Silverlight 2, C#] Testing Performance, Memory Usage

So after some code reviews and the like, I had decided to try and implement some of my core functionality a little different in order to *hopefully* decrease the memory allocation of my application.

Since Silverlight 2 does not appear to support the System.Diagnostics.Process class, I believe the only way to get similar information is via [Garbage Collector] System.GC.GetTotalMemory

System.GC.GetTotalMemory
public static long GetTotalMemory(
bool forceFullCollection
)

* Set forceFullCollection to true if you can wait for garbage collection to occur before doing the check.

* Returns the estimated number of bytes the application has allocated.

Difference Between GetTotalMemory() vs Windows Task Manager Memory Estimation
I have noticed QUITE a difference between the bytes returned from this function, vs. the Windows Task Manager estimation of the memory used by iexplorer while my app is running.

Siverlight Plugin Memory
One reason that I know for sure, is that the Task Manager takes into account the memory it takes to run the Silverlight plugin. I created an empty Silverlight project and when running it, it appeared to take up between 38,000kb to 40,624kb. Not sure why there was ever a difference, but every time I ran it I got a slightly different value. GetTotalMemory does not appear to include this cost and only counts the memory the app itself allocates.

Unmanaged Memory
GetTotalMemory only counts managed memory allocated by your application. If there is a memory leak for whatever reason, then that cost will not be included in the total.

There may be other reasons that the two memory estimations are different, but those are the two that I have come across so far.

.

Tuesday, December 30, 2008

[Silverlight 2] Unit Testing

This is more for my own reference, but here are some really good links I found to information about using the Silverlight Testing framework available to us.

Unit testing Basics [Jeff Wilcox]
Excellent Step by Step [Jeff Wilcox]
MSDN Download and Info
Basic Asynchronous Step by Step

I am probably abusing the framework with the way I have setup my test scripts, but I was looking to store state between each test so that I would not have to setup my application state every time I moved onto a new test.

I followed the main steps listed by Jeff Wilcox, however, I made a few alterations that would probably make him cringe ;)
  1. In each test cs file, I store an instance of the class I'm testing so that the state can be saved.
  2. In the PreparePage() function for each TestClass I check if that instance has been initialized. If it has, I do nothing, else I set it up. Since PreparePage is called before each TestMethod I want to make sure that my instance remains with the state of it's previous test.
  3. I name my tests, in order, alphabetically... often prefixed with "aa_[DoThis]", "ab_[ThenThis]". Since the tests appear to be ran in alphabetical order I want to keep a very scrict execution order so that my state should be known after every test.
  4. I have made all my Test Classes partial, and have created a seperate file "TestSetup.cs" that acts as a central location for me to decide which scipts I want to run and when. Making the class partial allows me to stick the [TestClass] assmbly directive in another file, which means I can comment out scripts as I see fit.
Example:
GraphicCanvas_test.cs


public partial class GraphicCanvas_test : SilverlightTest
{
private GraphicCanvas myCanvas;

[TestInitialize]
public void PreparePage()
{
if (myCanvas != null) { return; }
myCanvas = new GraphicCanvas();
}

...
}

TestSetup.cs

[TestClass] public partial class GraphicCanvas_test {} // Test script run
//[TestClass] public partial class PaletteManager_test {} // <-- Not run


I'm still playing around with unit testing framework, and I'm probably bending it how it wasn't meant to be bent - but I have yet to see something that would work better for me :)




.

Thursday, December 18, 2008

[Silverlight] Silverlight Spy - Awsome Visual Tool

While googling some random problem I was having, I bumped into this amazing [and free!] tool built by firstfloorsoftware which allows you to inspect any Silverlight application embedded in a given page.
The Explorer presents XAP Package, Isolated Storage, Application Styles, the UI Automation tree and the UI element structure of a Silverlight application. Explore the structure and view and edit the details of the selected UI element in the Details pane. Silverlight Spy works with any web page hosting Silverlight 2 content, just point the browser to the page and let the Spy figure it out.
Already this has saved me tons of heartache, as it allows me to easily traverse the visual tree of my application - which is really handy when I do so many dynamic interactions [adding/removing elements etc...]. And I haven't even begun to use the isolated storage inspection! Check it out :)

http://firstfloorsoftware.com/silverlightspy/introduction/



.

Thursday, December 11, 2008

[C#] Creating Custom Dependency Properties

Oh! I'm so excited... I think I actually got this to work for me :)
Please note that this is for creating simple DependencyProperties... I am not creating an attached property here.

I have a custom user control called GraphicGrid which consists of multiple line elements that draw up a grid. I also have a custom user control called PropertyEditor which allows for easy changes to specific DependencyProperties of a given object. I wanted to be able to change the grid color and grid spacing via the editor, so I decided this was the perfect chance to try and implement custom dependency properties.

Here are the basic steps to setting one up:

Step 1:
Register the custom dependency property. Here I create a new dependency propery and give it a name, what the property type is, what the owning object type is, and then in my case, I register a callback to be ran when the value is changed. Note that you do not need to setup a callback function [use null instead], unless you need specific things to happen when the value is changed:
public static readonly DependencyProperty GridLineStrokeProperty =
DependencyProperty.Register("GridLineStroke",
typeof(Brush),
typeof(GraphicGrid),
new PropertyMetadata(GridLineStrokeChanged));

Step 2 [if you setup a callback]:
If you have setup a callback if the value has been changed, then you need to create that function.
private static void GridLineStrokeChanged(DependencyObject o,
DependencyPropertyChangedEventArgs e)

{
GraphicGrid grid = o as GraphicGrid;

// Color lines.
foreach (UIElement line in grid.LayoutRoot.Children)
{
line.SetValue(Shape.StrokeProperty, e.NewValue);
}
}

Here, I cast the sender to a GraphicGrid, which I believe is acceptable since I have registered the property to GraphicGrid. Then I perform some actions with the new value... in my case I update all the lines in the grid with the new color.

Step 3:
Then, if you wish, you can create a local variable which gets and sets this dependency property.
public Brush GridLineStroke
{
get { return (Brush)GetValue(GridLineStrokeProperty); }
set { SetValue(GridLineStrokeProperty, value); }
}
Step 4:
Update the property at your will and whenever the value is changed, the line color will also be changed!


Update directly via the DependencyProperty:
GraphicGrid newGrid = new GraphicGrid ();
newGrid.SetValue(GraphicGrid.GridLineStrokeProperty,
new SolidColorBrush(Colors.Red));



Update via the local variable:
newGrid.GridLineStroke = new SolidColorBrush(Colors.Red);



BAM! Auto updating lines!!!
Special thanks to bryant on the Silverlight forums :)
.

Wednesday, December 10, 2008

[C#] Loading embedded XAML files into a project

I was looking for a way to load in a XAML file into my project; I wanted to be able to create a nice looking element without having to build it up dynamically in the C# code, and without having to download the XAML file from a server as I have been doing in some other places.

Turns out you can embed a file as a resource in a Visual Studio project and then open the resource and stream it out!
Step 1: Right click on your project folder and add the new or existing resource to your project.

Step 2: Right click the newly added file in your solution explorer, and select "Properties"

Step 3: Change the "Build Action" to "Embedded Resource". Now the file will be built in to your project as a resource and accessible as such.

Step 4: Open up a stream to the resource, read it out into a string and then use XAMLReader.Load to load up the element. I found this code on a forum, so there may be an easier way to do it... but this worked for me.

Stream s = this.GetType().Assembly.GetManifestResourceStream ("myNamespace.myFile.xaml");
string propertyStr = new StreamReader(s).ReadToEnd();
Panel myGrid = (Panel)XamlReader.Load(propertyStr);

And BAM... loaded xaml! Note that your XAML file must contain the namespace information in order for [System.Windows.Markup.]XAMLReader.Load to load correctly.

Example myFile.xaml:
<. Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<. /Grid .>


Have fun :)
.

Monday, December 8, 2008

[Silverlight 2, C#] Make a dashed border "move" [animate]

I was looking to make my newly dashed border on my rectangle look like it was "moving" [as you see commonly in some applications when selecting an item].

To do this I created a doubleanimation on the "StrokeDashOffset" property of the Rectangle.

<. UserControl.Resources .>
<. Storyboard x:Name="LassoAnimation" .>
<. DoubleAnimation
Storyboard.TargetName="lasso"
Storyboard.TargetProperty="StrokeDashOffset"
By="1"
To="8"
RepeatBehavior="Forever"
Duration="0:0:3"
SpeedRatio="3" .>
<. /DoubleAnimation .>
<. /Storyboard .>
<. /UserControl.Resources .>

...

<. Rectangle x:Name="lasso"
Stroke="Blue" StrokeThickness="1" StrokeDashArray="6,2"
StrokeDashOffset="0" / .>

In order for the animation to be smooth you need to set the "To" value to be the size of the dash plus the gap values. So in my example, 8.

Then, when I want the animation to start in my C# code, I set the correct width/height/top/left values for the rectangle and then call the LassoAnimation.Begin function and BAM! Moving dashed border!


.

[Silverlight, C#] Create a simple dashed border

It is simple to set a dashed border of any shape [in my case I was setting a Rectangle border] ... simply set the StrokeDashArray property.

StrokeDashArray = "[Length of dash],[Length of gap], ..."
You can repeat the dash/gap pairs to create different patterns on the same stroke.
XAML:
<. Rectangle ... StrokeDashArray="5.0, 2.0" ./>

C#:
Rectangle lasso = new Rectangle();
...
lasso.StrokeDashArray = new DoubleCollection { 5.0, 2.0 };


.