Monday, July 27, 2009

Silverlight 3 : Analytics Class Capabilities

I hope my last article on Out of Browser breaking changes was useful for you, Today I am going to talk about the Analytics Class provided by Silverlight 3 with a very small demo. For this, you don’t need anything special since Analytics class is already made available as built-in once you install Silverlight 3.

About Analytics Class :

You will find this under System.Windows Namespace,So you don’t need any other references to set inside your project beside System.Windows.This class exposes two main properties as :

  • AverageProcessorLoad - Gets how much of the CPU this process is using across all cores averaged together (This might be directly applicable for Multi-core processors environment,mine is Centrino machine and not Core 2, but results are averaged as per definition)
  • AverageProcessLoad - Gets how much CPU processing is being used across all cores averaged together.

Another one is there known as GPUCollection which is though not part of my demo, but it is used to get a collection of GpuInformation objects which each include details taken from a video driver. The collection is useful for multi-adapter cases. For more information on Analytics Class, kindly refer Silverlight Offline documentation.

In my demo, I have also used some of the properties of Media Element Control which generally people don’t use since for scenarios of just playing videos they might not be applicable. Those properties are self-explanatory so again refer documentation if you need any more information. Now our Demo

XAML Code :

<Grid x:Name="LayoutRoot" Background="White">
       <MediaElement x:Name="MyMedia" Height="154" AutoPlay="True" Source="Wildlife.wmv" Margin="3,8,279,0" VerticalAlignment="Top" />
       <Rectangle Stroke="Black" Margin="6,166,8,8">
           <Rectangle.Fill>
               <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                   <GradientStop Color="Black" Offset="0"/>
                   <GradientStop Color="#FF99ABFF" Offset="1"/>
                   <GradientStop Color="#FFF8EAFA"/>
               </LinearGradientBrush>
           </Rectangle.Fill>
       </Rectangle>
       <dataInput:Label x:Name="compcpu" HorizontalAlignment="Left" Margin="19,193,0,0" Width="120" Content="Computer CPU Usage" Height="20" VerticalAlignment="Top"/>
       <dataInput:Label x:Name="slcpu" HorizontalAlignment="Right" Margin="0,0,509,185" VerticalAlignment="Bottom" Content="Silverlight CPU Usage"/>
       <ProgressBar x:Name="pgbar1" Margin="154,193,286,0" Height="20" VerticalAlignment="Top"/>
       <ProgressBar x:Name="pgbar2" Margin="154,0,286,184" Height="20" VerticalAlignment="Bottom"/>
       <dataInput:Label x:Name="gpucpu" HorizontalAlignment="Left" Margin="21,0,0,154" VerticalAlignment="Bottom" Content="Download Progress"/>
       <ProgressBar x:Name="pgbar3" Height="20" Margin="155,0,285,150" VerticalAlignment="Bottom"/>
       <dataInput:Label HorizontalAlignment="Left" Margin="23,0,0,116" VerticalAlignment="Bottom" Content="Audio Stream Count :"/>
       <dataInput:Label HorizontalAlignment="Left" Margin="23,0,0,97" VerticalAlignment="Bottom" Height="13" Content="Buffering Progress :"/>
       <dataInput:Label HorizontalAlignment="Left" Margin="23,0,0,72" VerticalAlignment="Bottom" Content="Buffering Time :"/>
       <dataInput:Label HorizontalAlignment="Left" Margin="23,0,0,50" VerticalAlignment="Bottom" Content="Dropped Frame Per Second :"/>
       <dataInput:Label x:Name="txtBufferingTime" HorizontalAlignment="Left" Margin="212,0,0,71" VerticalAlignment="Bottom"/>
       <dataInput:Label x:Name="txtBufferingProgress" HorizontalAlignment="Left" Margin="213,0,0,92" VerticalAlignment="Bottom"/>
       <dataInput:Label x:Name="txtAudioStreamCount" HorizontalAlignment="Left" Margin="213,0,0,114" VerticalAlignment="Bottom"/>
       <dataInput:Label x:Name="txtDFPS" HorizontalAlignment="Left" Margin="212,0,0,49" VerticalAlignment="Bottom"/>
       <dataInput:Label Margin="0,0,238,26" VerticalAlignment="Bottom" HorizontalAlignment="Right" Content="Natural Video Width :"/>
       <dataInput:Label Margin="0,0,238,49" VerticalAlignment="Bottom" HorizontalAlignment="Right" Content="Natural Video Height :"/>
       <dataInput:Label Margin="0,0,238,116" VerticalAlignment="Bottom" HorizontalAlignment="Right" Content="Natural Duration :"/>
       <dataInput:Label Margin="23,0,0,26" VerticalAlignment="Bottom" Content="Current State :" HorizontalAlignment="Left"/>
       <dataInput:Label x:Name="txtCurrentState" Margin="213,0,0,25" VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
       <dataInput:Label x:Name="txtNtrlDur" Margin="0,0,94,115" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
       <dataInput:Label x:Name="txtNVH" Margin="0,0,94,46" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
       <dataInput:Label x:Name="txtNVW" Margin="0,0,94,23" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
   </Grid>

C# Code :

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace Silverlight3NewFeature
{
    public partial class Page : UserControl
    {
        Analytics analytics;

        public Page()
        {
            InitializeComponent();
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);           
        }

        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            if (analytics == null)
                analytics = new Analytics();
                pgbar1.Value = analytics.AverageProcessorLoad;
                pgbar2.Value = analytics.AverageProcessLoad;
                pgbar3.Value = MyMedia.DownloadProgress;

                txtAudioStreamCount.Content = MyMedia.AudioStreamCount;
                txtBufferingTime.Content = MyMedia.BufferingTime;
                txtBufferingProgress.Content = MyMedia.BufferingProgress;
                   txtDFPS.Content = MyMedia.DroppedFramesPerSecond;
                txtCurrentState.Content = MyMedia.CurrentState;
                txtNtrlDur.Content = MyMedia.NaturalDuration;
                txtNVH.Content = MyMedia.NaturalVideoHeight;
                txtNVW.Content = MyMedia.NaturalVideoWidth;

        }
    }
}

A surprise for few of you for that CompositionTarget_Rendering Event, Well CompositionTarget exposes one and only one event which we are using and which occurs when the core Silverlight rendering process renders a frame, Since both the properties of Analytics class which we are using are directly reflecting value which can get change at each instance (i.e CPU and Process Load). So Loaded event might not be a suitable event for such requirement. Please note that, I am aware that values from Analytics class returns float value and not complete integer, But my idea is to show overall average consumption, so I opt ProgressBar control and not label.

Few of you may not be impress by so many labels and may wish to print all values on some TextBlock under some stackpanel, Well then this code might be good for you :

String str;

str = "Audio Stream Count :" + MyMedia.AudioStreamCount + "\n"
    + "Buffering Progress :" + MyMedia.BufferingProgress + "\n"
    + "Buffering Time :" + MyMedia.BufferingTime + "\n"
    + "Dropped Frame Per Second :" + MyMedia.DroppedFramesPerSecond + "\n"
    + "Current State :" + MyMedia.CurrentState + "\n"
    + "Natural Duration :" + MyMedia.NaturalDuration + "\n"
    + "Natural Video Height :" + MyMedia.NaturalVideoHeight + "\n"
    + "Natural Video Width :" + MyMedia.NaturalVideoWidth + "\n";

and then assign that str to any of TextBlock as Text property.

Output will look like this :

SLAnalytics

I hope this small demo will help you to understand the capabilities of Analytics class in Silverlight 3, I will be back with much more soon.

Vikram.

1 comment:

Aashish Singh Negi said...

Sir please blog about SILVERLIGHT 3 + SKETCHFLOW !!!!!