Welcome to MSDN Blogs Sign in | Join | Help

Short Windows 7 ‘How To’ Videos

If you haven’t tracked them down already, you might be interested in this set of short videos showing off fun new features in Microsoft’s upcoming Windows 7 operating system. I didn’t know most of these features existed, and I found a number of them to be quite useful.

The features I liked the best involved simple techniques for handling multiple windows. My desktop is usually a crowded mess, and rather than pretending that we are all highly organized compulsive cleaners, the folks who built Windows 7 include lots of ways to help us clean up our chaos.

You can grab the task bar at the top of a window, shake it, and watch all the other windows on your desktop automatically minimize. There are several cool features of this type, including an explanation of that funny looking block down at the bottom right of the Windows task bar.

Most of these videos are about 1 minute in length, some as short as 30 seconds. I found watching them a useful way to pass a few minutes of my day.

The videos are kept here:

del.icio.us Tags:
Posted by Charlie Calvert | 0 Comments
Filed under: ,

Community Convergence LI

Welcome to the fifty-first edition of Community Convergence. In this post I’m simply going to highlight some of the great blogging activity produced by our team in recent weeks. Eric Lippert has been wonderfully productive. I’m beginning to wonder if we shouldn’t simply dedicate an entire section of the Internet to his work. I’ve also included a few pointers to the work of our friends in the F# world; both Luke and Luca played major roles in the C# world for many years, and it is fun to track what they are doing with F#.

Posts for the Team

Eric Lippert

Sam Ng

CSharp FAQ

Kirill Osenkov

Luke Hoban

Luca Bolognese

Charlie Calvert

kick it on DotNetKicks.com

Community Convergence L

Welcome to the 50th issue of Community Convergence. Now that Visual Studio 2010 Beta is out, I think it might be helpful to draw attention to the new dynamic programming and office development features from the C# team that appear in that release. The C# team defines the core syntax found in C# 4.0, and the IDE features that make it easy for developers to access those features. In this post, I’ll focus on language features, in upcoming post, I’ll focus on IDE features.

There are, of course, many new tools and APIs that will appear in Visual Studio 2010. In this post I’m focusing exclusively on core language features from the C# team itself, as opposed to features that come from the WPF, WCF, Silverlight, or other teams.

The text presented here is meant to provide a high level overview of these features. At the end of the article I will point you to more technical resources that will allow you to explore these features in more depth, and to read more precise, rigorous definitions of the new features in C# 4.0.

Language Features

Dynamic programming and enhanced interaction with Office are the main theme in C# 4.0. Dynamic programming is a means of writing code that does not rely on a static types linked at compile time. Traditionally C# has been a strongly typed language defined in large part by static types that must be declared explicitly at compile time. For instance, string, int, and object are all strongly typed static types that are resolved at compile time. A dynamic type is not linked at compile time, but is instead resolved at run time.

Why should C# developers care about dynamic programming? Isn’t the strongly typed nature of the C# language one of the language’s best features? The answer to this question is a resounding yes. Strong typing is one of the great advantages of the C# language, and the team expects most developers to continue to write strongly typed code nearly all the time. There is nothing in the new C# 4.0 features that prevents you from continuing to exclusively write strongly typed code, if that is what you prefer.

However, there are occasions when it is convenient to write dynamic code. For instance, languages such as Python and Ruby are dynamically typed. It is awkward, and sometimes nearly impossible, to call into these languages from a strongly typed language such as C# 3.5. The Office API is also difficult to call from C# 3.5; it has long been awkward for C# developers to call into Office using the current set of language features.

C# 4.0 is adding dynamic features so that it will be easier for developers to call into dynamic languages such as Python, and into more flexible APIs such as Office. You can think of the entire dynamic programming effort as a move by the C# team to fill in existing holes in the language. C# has always provided a great way to write strongly typed code, now we’re adding support for dynamic code, and for calling into Office applications.

The team has broken out the new features in C# 4.0 into four categories, all but the last of which are directly related to dynamic programming or Office development:

  • Dynamic Lookup
    • A syntax for making calls into dynamic languages and APIs.
  • Named and Option Arguments
    • Allows developers to easily call into and create methods that support optional parameters. This is a big aid to Office developers since the Office API’s make heavy use of optional parameters.
  • COM Interop
    • Language features that make it easier to call COM objects. When calling COM objects you can now omit the keyword ref, you need to make fewer casts, and you no longer need depend on heavy-weight files called Primary Interop Assemblies, or PIAs.
  • Variance
    • Covariance and contravariance have nothing to do with dynamic programming or Office development. Instead, they represent a small, very technical enhancement to the language that makes it easier to use inheritance when writing generic code. In general, this feature ensures that the language behaves as expected, rather than forcing you to rewrite code that looks like it should compile. For instance, the following code has a natural syntax that looks like it should work, but it does not work in C# 3.5. The upcoming changes in C# 4.0 ensure that it will compile:

      IEnumerable<string> strings = new List<string>();
      IEnumerable<object> objects = strings;

That’s the end of our quick overview of the new features in the C# 4.0 language. Again, remember that there are many other new features of in Visual Studio, and many new enhancements to existing technologies such as WPF, WCF, Silverlight and LINQ. In this post, I’ve focused exclusively on changes to the basic syntax of the language that have been implemented by the C# team itself.

References

Here are few references for people who want to explore this subject in more depth. A guide for developers interested in all things related to C# 4.0 is the C# Futures site on Code Gallery. There you will find a downloads page that contains the following key resources:

  • An excellent and definitive white paper on C# 4.0 language features. Mads Torgersen was the primary author of this document.
  • The C# 4.0 samples

Other important resources include C# 4.0 sections Eric Lippert’s and Sam Ng’s blogs:

kick it on DotNetKicks.com

Dotfuscator in Visual Studio 2010

Those of you who are using Visual Studio 2010, Beta 1 have probably noticed the Dotfuscator Community edition listing in the VSTS Tools menu. Dotfuscator is made by the the developers at PreEmptive Solutions, and they have begun a blog detailing the features available in Dotfuscator, and how to use them. Here is a link to one of their first posts, and here is another post you might find interesting.

On their web site, PerEmptive says: “Dotfuscator Software Services – Community Edition is shipping within Visual Studio 2010 and it’s far more than an obfuscation tool. With our post-build, code injection platform, developers can track application and feature usage, defend against tampering, and force application expirations.”

Community Convergence XLIX (IL)

Welcome to the 49th edition of Community Convergence. The big excitment of late has been the recent release of the Visual Studio 2010 Beta. If you have downloaded it yet, you should waste no time in heading over to the product page and downloading the files. As usual for betas of this type, I would recommend running it inside a Virtual Machine, or on a machine that you can afford to entirely reformat.

I’ve also included a number of links to articles from team members, many of whom discuss C# 4.0 programming issues that are related to the Visual Studio 2010 beta. There has been a lot of excellent blogging activity lately, so go ahead and get started digging into this great information.

Eric Lippert

Kirill Osenkov

Luca Bolognese

Sam Ng

kick it on DotNetKicks.com

Silverlight Animation Part II: Sprites

In the previous post in this series, you learned how to create a simple animation with Silverlight. The next step is to learn how to create animated objects called sprites. This post will also explain how to ensure that a Sprite’s movement is restricted to a bounded area, as shown below in Application 1. Logic like this can be used in simple games, or in programs that want to use animation to capture or focus the user’s attention.

Application 1: Two sprites moving in a bounded area

The XAML

As shown below in Listing 1, the XAML for this application is very simple. A light green Grid hosts a TextBlock and a dark green Canvas named myCanvas. The Canvas contains a red and blue Rectangle named myRect and purple and blue gradient Image named myImage. The TextBlock, shown at the top of the application, display a string showing the width and height of the Canvas, and the current X and Y location of the Rectangle.

Listing 1: The XAML which serves as the starting point for the simple animation shown in above in Application 1.

<UserControl x:Class="SilverlightAnimatedTimer01.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="LightGreen">            
        
        <TextBlock x:Name="myTextBlock" TextAlignment="Center" />
        
        <Canvas Background="Green" Name="myCanvas" Height="250" Width="350" Loaded="StartTimer">             
            
            <Rectangle Stroke="Red" StrokeThickness="5" 
                       Width="25" Height="25" 
                       Fill="Blue" 
                       Name="myRect" />                            
            
            <Image Source="Images/MrBlue.png" 
                   Name="myImage" />
            
        </Canvas>
    </Grid>
</UserControl>

The Canvas object has a Loaded event associated with it, which is used to start a Timer. Code of this type was described in the previous article in this series, so I will not discuss the implementation of the Timers again in this post. I will however, reference the relevant code once near the end of this article.

Note also that from a technical perspective it doesn’t matter which control control contains the Loaded event. In this case I’ve chosen the Canvas, but I could just as easily have moved it to the TextBlock. The decision to associate the event with the Canvas was an aesthetic, rather than a technical, decision.

C# Code

The code we create for this program is broken up into two files. The first file defines  the Sprites that move across the surface of the Canvas, and the second part defines the program’s very simple logic and structure. Again, for aesthetic, rather than technical reasons, I decided to put the Sprite code in its own library. This helps to establish a design principle that I believe will prove useful as the program’s code grows more complex. However, from a technical perspective, the code could just as easily have been placed in the main program.

Figure 1 gives an overview of the program’s structure. The main program logic is stored in the Silverlight project, primarily in the file called GameCore.cs. The logic for the Sprites is stored in the SilverlightGameLibrary, primarily in the file called SpritesLib.cs. Again, I do this not out of necessity, but simply because I feel it povides a neat division of labor that helps make the program easy to maintain. Notice also that since libraries form discrete reusable blocks of code, they could easily be transferred to a second project which required similar logic.

Figure00

Figure 1: The Solution Explorer provides an overview of the Solution’s structure. Note that there are three projects in this solution, one of the Silverlight interface, one for ASP.NET web code, and one of the library where shared code can be stored.

The Sprites

In applications of this type, it is simplest to create a small Sprite class that encapsulates the behavior of the objects that move across the screen. There are many different ways to compose such a class, but most people follow a pattern similar to the one shown in Figure 2.

Figure01

Figure 2: A Simple Sprite class with two descendants, one that encapsulates the Rectangle type, and one that encapsulates the Image type.

The structure of this class hierarchy is easy to discern. A simple Sprite class has two descendants, one tailored for use with Rectangle controls, and one for use with Image controls. The common code which applies to both types of controls is stored in the base class, which is called Sprite.

With of some its lengthier methods foreshortened, the Sprite class looks like this:

public class Sprite
{
    internal enum MoveType { None, Up, Down, DownLeft, DownRight, UpLef

    internal Rect containerBounds = new Rect();
    internal FrameworkElement SpriteShape { get; set; }

    public Double Y { get; set; }
    public Double X { get; set; }
    private Double incValue = 1.0;
    internal MoveType ShapeMoveType { get; set; }

    public Sprite()
    {
        ShapeMoveType = MoveType.None;
    }

    public Sprite(FrameworkElement initSpriteShape, Double initX, Doubl
        : this()
    {
        this.SpriteShape = initSpriteShape;
        this.X = initX;
        this.Y = initY;
    }

    internal void CheckBounds()
    {
       // Code omitted here        
    }

    virtual public void Move()
    {
        CheckBounds();
        // Code omitted here 
        SpriteShape.SetValue(Canvas.LeftProperty, X);
        SpriteShape.SetValue(Canvas.TopProperty, Y);
    }    
    public void SetBounds(int initWidth, int initHeight)
    {
        containerBounds.X = 0;
        containerBounds.Y = 0;
        containerBounds.Height = initHeight;
        containerBounds.Width = initWidth;
    }
}

The heart of the Sprite class are the SpriteShape, X and Y fields:

internal FrameworkElement SpriteShape { get; set; }

public Double Y { get; set; }
public Double X { get; set; }

These two points define the upper left corner of a sprite. The Y field is the top bound, and the X field defines the left bound of the sprite. The SpriteShape field derives from FrameworkElement, which is a base class for both the Image and the Rectangle type. This base type contains enough logic to allow us to use the type to animate the Sprite as it moves across the canvas.

A method called SetBounds is used to define the range over which we want the Sprite to travel. In this program, the Rect type called containerBounds is initialized to values defining the Left, Top, Width and Height of the Canvas on which the sprites will live. The code states, in effect, that the sprites are not allowed to wander outside the bounds of the Canvas. We will revisit this code in the next section of the program, where you will see exactly how the bounds are initialized.

An enumeration captures the six basic movements of which our sprites are capable:

internal enum MoveType { None, Up, Down, DownLeft, DownRight, UpLeft, UpRight };

In a more complex program, we could replace these simple movements with complex calculations, or even with code based on the physics of a particular object that you might want to encapsulate in your program. For instance, advanced mathematicians could describe the physics of a pool table, or of the waves on an ocean. In this case, however, the simple type defined here meets our needs.

A lengthy but logically very simple method called CheckBounds is used to compare the current X and Y location of the Sprite with the known bounds of its container. If the Sprite threatens to move outside these bounds, then is course is changed.

NOTE: Code I will show you later initializes the direction the Sprite is moving as the program begins. For instance, the Image control is initialized to begin moving down and to the right (MoveType.DownRight), while the Rectangle control is initialized to move down and to the left (MoveType.DownLeft).

An abbreviated version of the CheckBounds method is shown in the excerpt from the Sprite class shown above. Here is the complete definition of the method:

internal void CheckBounds()
{
    if ((Y + SpriteShape.ActualHeight) > containerBounds.Height)
    {
        if (ShapeMoveType == MoveType.DownRight)
        {
            ShapeMoveType = MoveType.UpRight;
        }
        else
        {
            ShapeMoveType = MoveType.UpLeft;
        }
    }
    else if (Y < 0)
    {
        if (ShapeMoveType == MoveType.UpRight)
        {
            ShapeMoveType = MoveType.DownRight;
        }
        else
        {
            ShapeMoveType = MoveType.DownLeft;
        }
    }
    else if (X + SpriteShape.ActualWidth > containerBounds.Width)
    {
        if (ShapeMoveType == MoveType.UpRight)
        {
            ShapeMoveType = MoveType.UpLeft;
        }
        else
        {
            ShapeMoveType = MoveType.DownLeft;
        }
    }
    else if (X < 0)
    {
        if (ShapeMoveType == MoveType.DownLeft)
        {
            ShapeMoveType = MoveType.DownRight;
        }
        else
        {
            ShapeMoveType = MoveType.UpRight;
        }
    }
}

The first line of code in this method checks if the sprite is about to wander off the lower edge of the Canvas. If it is, then its trajectory is changed from a downward to an upward direction. In particular, if the shape is moving down and to the right, then it is told to start moving up and to the right, and so on.

The first else block in the code checks if the Sprite is about to move off the top of the canvas. If it is, then it is told to begin moving in a downward direction, and so on.

The Move method defines the engine the actually drives a Sprite across the canvas. Again, an abbreviated version of this method was shown in the original version of the Sprite class shown above. Here is the complete method:

virtual public void Move()
{
    CheckBounds();

    switch (ShapeMoveType)
    {
        case MoveType.None:
            break;

        case MoveType.DownRight:
            X += incValue;
            Y += incValue;
            break;

        case MoveType.DownLeft:
            X -= incValue;
            Y += incValue;
            break;

        case MoveType.UpRight:
            X += incValue;
            Y -= incValue;
            break;

        case MoveType.UpLeft:
            X -= incValue;
            Y -= incValue;
            break;

        default:
            throw new Exception("Bad move type");
    }

    SpriteShape.SetValue(Canvas.LeftProperty, X);
    SpriteShape.SetValue(Canvas.TopProperty, Y);
}

The code begins by calling the CheckBounds method, to ensure that the Sprite is not set on a course that will allow it to wander off the straight and narrow path of virtue. The program then enters a switch statement, which defines how to move the sprite in five of the seven possible directions in which it can move. This program never moves the sprite straight up or straight down, though it would not be hard to see how to define the code to implement that logic. A value called incValue is declared to define how far the sprite moves. In this version of the program, that value is set to one, which means that the sprite moves one pixel at a time. If you wanted the sprite to move faster, you could set this value to higher number, or you could change the rate at which the program’s timer is called.

The logic for moving the sprite down and to the left and right, or up and to the left and right, is so simple that I will not enumerate it here. it is simpler for you to simply look at the code in the Move method, and to derive your understanding of its logic from what you see there.

If you look up at Figure 1, you can see that I create two simple descendants of the Sprite class: one for the Rectangle and one for the Image. I do place a small amount of logic in these classes, but really, they are place holders in case we find some reason later on for customizing the behavior of the Rectangle or of the Image. For instance, if you wanted to change the color of the border of the Rectangle, that logic would apply only to Rectangles, and not to Images. Hence it would belong in the MrRect class, and not in the base class.

I’ll show you only one of these classes, since they are nearly identical:

public class MrBlue : Sprite
{
    public Image myImage { get; set; }

    public MrBlue()
        : base()
    {

    }

    public MrBlue(Image initImage,
        Double initX, Double initY)
        : base(initImage, initX, initY)
    {
        myImage = initImage;
        ShapeMoveType = MoveType.DownRight;
    }        
}

You can see that this class initializes the direction the Image moves in, setting it to MoveType.DownRight.  I also save a copy of the original shape. Neither of these bits of logic really justifies the existence of this class, but I create it anyway because I feel – for the reasons outlined above -- that it is likely to be useful in later iterations of this type of program.

Program Logic

Now that the Sprite logic is defined, the program logic is very easy to write. I define a simple class called GameCore, and create an instance of MrBlue and MrRect inside it. Also included in the class is a method called:

  • MainLoop for driving the movement of the sprites
  • ShowProgramData for updating the user with an ongoing description of the program’s state
  • InitBounds for defining the range inside which the Sprites can move.
public class GameCore
{
    private MrBlue mrBlue = null;
    private MrRect mrRect = null;
    private Page page = null;        

    public GameCore(Page page)
    {
        this.page = page;
        mrBlue = new MrBlue(page.myImage, 0.0, 0.0);
        mrRect = new MrRect(page.myRect, 325.0, 0.0);
        InitBounds();
    }

    public void MainLoop()
    {
        mrRect.Move();
        mrBlue.Move();
        ShowProgramData();
    }

    private void ShowProgramData()
    {
        string xValue = Strings.PadLeft(mrRect.X.ToString(), '0', 3);
        string yValue = Strings.PadLeft(mrRect.Y.ToString(), '0', 3);
        if (Double.IsNaN(page.myCanvas.ActualHeight) || Double.IsNaN(page.myCanvas.ActualWidth))
        {
            page.myTextBlock.Text = "Not a number";
        }
        else
        {
            page.myTextBlock.Text = "Height " + page.myCanvas.ActualHeight.ToString()
                + " " + "Width = " + page.myCanvas.ActualWidth.ToString()
                + " " + "X = " + xValue
                + " " + "Y = " + yValue;                
        }
    }

    private void InitBounds()
    {
        mrRect.SetBounds(Convert.ToInt32(page.myCanvas.ActualWidth), Convert.ToInt32(page.myCanvas.ActualHeight));
        mrBlue.SetBounds(Convert.ToInt32(page.myCanvas.ActualWidth), Convert.ToInt32(page.myCanvas.ActualHeight));
    }
}

The constructor is used simply to initialize the starting places for the Image and Rectangle controls, and to initializes the bounds over which they can range.

The timer for the program is implemented in the file called by default Page.xaml.cs. As described in previous posts, this file is auto-generated by the Visual Studio IDE. It is used to drive the program logic by repeatedly calling the method called MainLoop. Here is the implementation of the Timer:

public partial class Page : UserControl
{

    GameCore gameCore = null;

    public Page()
    {
        InitializeComponent();
        gameCore = new GameCore(this);                   
    }

    private void StartTimer(object sender, RoutedEventArgs e)
    {
        System.Windows.Threading.DispatcherTimer myDispatcherTimer = 
            new System.Windows.Threading.DispatcherTimer();
        myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 10); 
        myDispatcherTimer.Tick += new EventHandler(Each_Tick);
        myDispatcherTimer.Start();
    }        
    
    public void Each_Tick(object o, EventArgs sender)
    {
        gameCore.MainLoop();
    }
}

The MainLoop method calls the Move methods of the two shape controls:

public void MainLoop()
{
    mrRect.Move();
    mrBlue.Move();
    ShowProgramData();
}

It also calls a method named ShowProgramData, which allows you to display any other information you want to share with the user. In this case, I use it to display in a TextBlock the current location of the Rectangle control.

Summary

In this post, you have seen how to create a simple Silverlight animation which moves simple sprites inside a bounded rectangle. The post describes how to create simple Sprite classes that know how to move in pre-defined directions across a drawing surface, and which know how to limit their movement to a bounded rectangle.

There is quite a bit of code in this post, but most of it is extremely simple. In general, programs of this type are very easy to create, but they provide you with a framework from which you can build a wide variety of animations that can be used to decorate a standard program or to serve as the core engine for a simple game.

Download the code from the LINQ Farm on Code Gallery.

kick it on DotNetKicks.com

Silverlight Layouts Part 1

This is the third in a series of posts on Silverlight. The text focuses on creating a basic interface for a Silverlight application and explores simple ways to work with Grid controls that are divided up into Rows and Columns.

So far, I’ve added the following posts to the Silverlight series:

Related Posts

Source Code

UserControls

Silverlight 2.0 projects typical use a combination of XAML and C# or VB code. XAML stands for Extensible Application Markup Language. It is pronounced Zamel, and it rhymes with the word camel.

When you create a new Silverlight project, the following XAML is produced:

<UserControl x:Class="SilverlightApplication3.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">

    </Grid>
</UserControl>

Here you see two controls:

  • A UserControl
  • And inside it, a Grid

A UserControl is a standard Silverlight type from which developers can derive their own custom controls. You can derive any type of control you want from a UserControl. However, the UserControl shown in the code quoted above usually acts as a container for your interface. Typically, developers fill this container with a series of Buttons, Textboxes and other simple elements that define an interface of some type.

You can draw a very rough analogy between a Form in a Windows Forms application and this UserControl in a Silverlight application. Just as you use a Form to define the interface for Windows application, you use a UserControl to define the interface for your Silverlight application.

It’s important to remember, however, that this control is, by default, embedded inside an ASP.NET Web Application Project. You could, therefore, also view the control as an interface element inserted into an ASP.NET web application. In our case, however, we are focusing exclusively on the Silverlight portion of the application, so the Windows Forms analogy is not too inappropriate, so long as you don’t take it overly literally, and so long as you remember that UserControls can be used for entirely different purposes in other contexts. You can create any type of custom control you want from a UserControl, but in this context, the UserControl is a container for your interface.

Grids

Inside the UserControl is a Grid. If you want, you can use this grid as the host for most of the controls in your program. You could, for instance, place a button inside it:

<UserControlx:Class="SilverlightApplication11.Page"
  
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  
Width="400"Height="300">
    <
Gridx:Name="LayoutRoot"Background="White">
        <
ButtonContent="OK"/>       
    </
Grid>
</
UserControl>

This XAML code produces the following output:

Figure01

Figure 01: A Grid control hosting an OK button. 

This seems like a good start, but if you try to add another button, you will see that things don’t work out as you might have expected. Here is the code for adding a second button:

<UserControl x:Class="SilverlightApplication11.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Button Content="OK"/> 
        <Button Content="Cancel"/>
    </Grid>
</UserControl>

The output from this code looks like this:

Figure02

Figure 02: A Grid control that hosts a Cancel button which obscures an OK button.

There is our Cancel button, as big as life. But what happened to the OK button? It appears to be obscured by the Cancel button. In other words, the Grid control is not allowing us to display two buttons at once, but instead is taking one button, and allowing it fill the entire interface. In same situations, this might be exactly what we want, but in this case it is working at cross purposes to our goal.

As you have no doubt surmised, the Grid control, as it is currently configured, will not produce the behavior we want. There are, in fact many ways to get the grid control to display multiple buttons. Here is one way:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Button Grid.Row="0"  Content="OK"/> 
    <Button Grid.Row="1" Content="Cancel"/>
</Grid>

 

This code defines two rows in the grid: one fills the top half of the grid, and the second fills the bottom half. We have added code to our Button declarations asking the Ok button to be hosted in Row 0, and the Cancel button to be hosted in Row 1. Here is the result:

Figure03

Figure 3: A Grid control with two rows. The first row hosts an OK button, the second a Cancel button.

If you need columns, rather than rows, then use this code:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Button Grid.Column="0"  Content="OK"/> 
    <Button Grid.Column="1" Content="Cancel"/>
</Grid>

Here is the result:

Figure04

Figure 4: A Grid control with two columns, each of which hosts a button.

If you want both rows and columns, then write code like this:

<UserControl x:Class="SilverlightApplication11.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>

        <Button Grid.Column="0" Grid.Row="0" Content="OK"/> 
        <Button Grid.Column="1" Grid.Row="0" Content="Cancel"/>
        <Image Grid.Column="0" Grid.Row="1" Source="Images/BlueLight.png" />
        <Image Grid.Column="1" Grid.Row="1" Source="Images/RedLight.png" />
    </Grid>
</UserControl>

This interface produces four sections inside the grid. We could have left the two new spaces empty, but I thought it would be less confusing if I put something inside them. To keep the code simple, I’ve added two Image controls and placed two simple bitmaps in them. I then use both the Grid.Column and Grid.Row properties in the Button and Image controls to designate where I want the images and buttons to appear.

Note that I store that Images in a directory called Images. You can create project directories of this type by writing clicking on your project in the Solution Explorer, and choosing Add | New Folder. After you copy the bitmaps into the Images directory, click the Show All Files button at the top of the Solution Explorer to make the bitmaps visible. Then right click on the images and explicitly add them to your project. When you are done, your work Solution Explorer might look something like this:

Figure05

Figure 5: Creating an Images directory that contains two bitmaps.

Taken together, all of the XAML code shown in the previous examples produces the following results, where the blue and orange areas are the bitmaps that I stored in the Images directory:

Figure06

Figure 6: A Grid control with two rows and two columns. The control hosts two buttons and two images, one in each quadrant of the Grid.

Summary

That’s probably enough for this post. There is obviously a great deal more to be said about Grid controls in particular, and Silverlight interfaces in general, but this can serve as an introduction to the topic. The next article in this series will continue in this same vein, discussing, layouts, Grid controls, and StackPanels.

References

Download the source for this post from the LINQ Farm on Code Gallery

kick it on DotNetKicks.com

Silverlight Simple Animation

This post is one of series on Silverlight. In this article the focus is on a technique that uses a timer to produce simple animations. I will follow this post with at least one additional article on Silverlight animation.

Silverlight has several built in techniques for animating controls. Many of these technologies are particularly useful for creating simple animations meant to decorate a web page with eye catching movement that draws the reader’s attention. In this post I will skip over these decorative technologies, and instead show how to create a simple animation using a technique similar to those used in many games.

Though Silverlight is a web technology, the technique I will focus on is very similar to the same technology you would use in most standard programming languages such as C++ or Delphi. Though the animation technology I will focus on is often used in game programming, there are many different reasons why you might want to create this kind animation, particular in scientific programming, or code that attempts to illustrate complex numeric data.

You will find that Silverlight makes the type of animation I want to focus on very simple. As such, it makes a good place to start an exploration of Silverlight animation. I want to emphasize, however, that there are other Silverlight techniques that use Storyboards and the DoubleAnimation and PointAnimation controls that might be more appropriate if you just want to add a bit of color to a web page. You can add a bit more complexity to those technologies by exploring key frames. See, for instance, the DoubleAnimationUsingKeyFrames control.

In the example shown in this post I will create two simple “sprites” that I will animate by moving them smoothly and rapidly at an angle across a web page, as shown in Figure 1. In Figure 1, the blue Rectangle with the red border started its brief but illustrious career near the upper right corner of the green field, and is moving down toward the bottom left corner. The purple and blue gradient image started at the upper left corner and is moving at an angle toward the bottom right of the green Canvas control.

Figure01

Figure 1: Two simple sprites moving at angles across a green field.

Below you can see a live version of this application. Because the animation is quite brief, you will need to press the refresh button to see it in action.

The sprites in this example move smoothly and at a reasonable pace across the green surface. This is very important, as users frequently denigrate applications that have jerky or overly slow animations.

In the next post in this series I will show how to get more control over the sprites, and how to get them to “bounce” off the edges of a window so that they stay confined in a defined space, such as the green field shown here.

Creating the XAML

Silverlight’s reliance on WPF frequently leaves developers with a choice between implementing their logic in XAML or in standard C# code, or in some combination of the two. Perhaps because my background is a C# developer, I tend to write only a minimal amount of XAML, and to implement most of my logic in C# code.

The XAML for this example is extremely simple:

<UserControl x:Class="SilverlightAnimatedTimer01.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">            
        
        <Canvas Background="Green" Name="myCanvas" Loaded="StartTimer">
            <Rectangle Fill="Blue" Stroke="Red" StrokeThickness="5" 
                       Width="25" Height="25"  Name="myRect" />
            
            <Image Source="Images/MrBlue.png" Name="myImage" />
        </Canvas>
    </Grid>
</UserControl>

The code for the UserControl and the Grid is boilerplate Silverlight code produced by the IDE when any new Silverlight project is created. I’ve added only three items:

  • A Canvas called myCanvas which has an event called StartTimer that is called when the Canvas is first loaded
  • A blue and red Rectangle control that is 25 pixels square
  • An Image control which is also 25 pixels square. It is referenced inside the program as myImage

The XAML puts both controls in the upper left corner of the Canvas, which means that in design mode one will be hidden behind the other. The C# code I show in the next section moves the Rectangle off to the right of the Canvas, so that it has a unique location at run time.

The Timer

Animations of the kind shown here are usually run off a timer which produces a kind of miniature application loop that is called at regular intervals and which acts as engine to drive the animation forward. The loop is started when the Canvas is loaded:

private void StartTimer(object sender, RoutedEventArgs e)
{
    System.Windows.Threading.DispatcherTimer myDispatcherTimer = 
        new System.Windows.Threading.DispatcherTimer();
    // Call the timer once every 10 milliseconds
    myDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 10); 
    myDispatcherTimer.Tick += new EventHandler(MoveShapes);
    myDispatcherTimer.Start();
}        

This code is pulled nearly verbatim from the Silverlight documentation. It begins by creating a timer, then asks that the timer be fired once every ten milliseconds. A method called MoveShapes will be called whenever the timer is fired. Finally the code Starts the timer.

Here is the MoveShapes method, which is called by the timer once every ten milliseconds:

Double imageX = 0.0;
Double imageY = 0.0;
Double rectX = 275.0;
Double rectY = 1.0;
Double incValue = 1.0;
public void MoveShapes(object o, EventArgs sender)
{
    imageX += incValue;
    imageY += incValue;
    rectX -= incValue;
    rectY += incValue;            

    myRect.SetValue(Canvas.LeftProperty, rectX);
    myRect.SetValue(Canvas.TopProperty, rectY);

    myImage.SetValue(Canvas.LeftProperty, imageX);
    myImage.SetValue(Canvas.TopProperty, imageY);
}

This method is passed two parameters. The first is copy of the timer. You can use this object to disable or change the traits of the timer.

This code in the MoveShapes covers several lines, but its structure is very simple. I’ve declared values to track the current X and Y location of the upper left hand corner of the Image and Rectangle controls. Note that I initialize the rectX field to 275.0. It is this value that moves the Rectangle control over to he right of the Canvas at program start up, so that it is no longer hidden behind Image control. Needless to say, in the next article in this series I will create separate objects for each sprite. At this stage however, I’m focusing on showing you the basic animation techniques in the least possible amount of code.

The last lines show how to call the SetValue method of the Rectangle and Image control in order to move the control across the surface of the Canvas. Silverlight provides us with a nice bonus feature here by automatically handling this transformation. In particular, it erases the original image of the control and then repaints it in the new location. In most computer languages, I would have had to manually write the code to erase the old image.

Note that the MoveShapes method begins by incrementing or decrementing the fields that specify the location of the controls. This allows us to define how we move the controls across the surface of the Canvas. It is, however, the call to SetValue that actually transforms the location of the controls. The end result is a smooth animation of the controls across the surface of their container.

The best way to see this animation in action is to download the code and try it yourself. Remember that you need to first install the Silverlight integration for Visual Studio 2008, as described in the Get Started section of the Silverlight web site.

Summary

The technique for animating controls that I’ve described in this article is very easy to use. Silverlight provides all the tools we need to set up simple animation without requiring any real effort on our part. As a result we can focus our energy on simply describing the path that we want our controls to follow. In particular, you need only:

  • Set up a timer that calls a method you define at discreet intervals.
  • Define the method called by the timer, and ensure that it contains logic for moving your controls.

As mentioned above, I’ll follow this post with at least one additional article that describes additional techniques for animating sprites. Those techniques require us to write a bit more code than that shown here, but at heart they are also very simple and easy to understand.

kick it on DotNetKicks.com

Creating a New Silverlight Project in Visual Studio 2008

This post is part of a series of articles on Silverlight. The purpose of this post is describe how to start a new Silverlight project or how to add a new or existing Silverlight project to an existing ASP.NET Web Application.

To be able to follow the discussion presented in this post you will need to install Silverlight support to Visual Studio. I will not discuss the details of that install, other than to say that you can download the necessary files from the Get Started page of the Silverlight site. Note that you need Visual Studio 2008 Service Pack 1 or the install will fail. If the various options for creating Silver projects discussed in this post are not available in your copy of Visual Studio 2008, then the likely cause is that you have not yet installed Silverlight support for Visual Studio.

Creating a New Silverlight Project

You have several options when creating a new Silverlight project. In this post, I will focus on creating a Silverlight project embedded in an ASP.NET application, but I will discuss the other options available to you. I’m choosing to embed the Silverlight project in an ASP.NET application because that is the default option, because ASP.NET applications are popular, and because the deployment options for these kinds of projects are simpler for beginners.

You will end up creating a solution that owns two projects. Conceptually, that will look something like this:

  1. The Solution File, which will own two projects
    1. The first project is the ASP.NET host application.
    2. The second is the Silverlight project which will end up being embedded as an interface element inside the ASP.NET application.

Begin by choosing File | New Project from the Visual Studio menu. The default hotkey is Ctrl + Shift + N. The dialog shown in Figure 1 appears.

In the Project Types window in the upper left section of Figure 1, choose Silverlight. In the Templates window on the upper right of Figure 1 choose Silverlight Application.

The Name field in the New Project dialog lets you specify the name of your Silverlight project, which in our case will be StarterApp. The Solution Name field lets you specify the name for the solution that will own both your Silverlight project and its ASP.NET host. Again, lets call this solution StarterApp. You can now click the OK button.

 

 Figure01

Figure 1: The New Project Dialog is reached by choosing File | New Project from the Visual Studio menu. Select Silverlight from Project types tree view, and Silverlight Application from the Templates list view control.

After closing the New Project dialog by pressing the OK button, the dialog shown in Figure 2 appears. This dialog is designed to allow you to create a solution that combines a Silverlight project with a host project, which in our case is an ASP.NET application.

Figure02

Figure 2: The default selections in the Add Silverlight Application dialog allow you to specify an ASP.NET project type and its name.

There are several different Project Types available when you create an ASP.NET Web project that hosts your Silverlight project. These include the following three options:

  1. The default ASP.NET Web Application Project shown in Figure 2
  2. An ASP.NET Web Site
  3. An ASP.NET MVC Web Project

Since we are focusing on Silverlight, this is not the place to go into a discussion of the relative values of these three options. Lets just keep things simple and assume that you want to create an Application Project. If you want to choose one of the other options, that will not materially effect the design of your Silverlight project. In other words, you can host the same Silverlight project in all three of these types of ASP.NET Web Projects.

If you choose to “Automatically generate a test page to host Silverlight at Build time,” then no host project is created. Hence, there are no options for configuring your solution. In other words, the Options section shown in the bottom half of Figure 2 is empty. When you press the OK button in the Add Silverlight Application dialog, the solution created contains only the one Silverlight project, and no host project. When you run the project, a file called TestPage.html is automatically generated to host the Silverlight project. This file is not included in your project, but you can browse to the Bin\Debug directory for your project to view it. You an also go online and view the official Microsoft description of how to embed a Silverlight project in an HTML page. There you will find a description of the code found in TestPage.html.

Assuming that you chose to embed your Silverlight project in an ASP.NET application, you will end up with a solution that contains two projects, as shown in Figure 3. The first project, called StarterApp, contains the Silverlight code that we will focus on in this series of posts. The second project, called StarterApp.Web, is an ASP.NET application that will host our Silverlight code.

Figure03

Figure 3: The Solution Explorer shows that a typical default Silverlight solution contains both an ASP.NET Web project and a Silverlight project.

If you look at the bottom half of Figure 3 you see the list of files in StarterApp.Web. You can see that this ASP.NET project has been modified to host a Silverlight project. The code that hosts the Silverlight project is strictly boilerplate code which performs its job without any need for modification on your part.

As an aside, I’ll mention that the file Page.xaml, which is highlighted in Figure 3, contains the key Silverlight code that will focus on in this series of posts. The posts in this series that succeed this one will describe the code in that file, and how you can modify it to create an interface for your Silverlight project.

Adding Silverlight to an Existing ASP.NET Web Project

There are two options to cover when discussing how to add a Silverlight project to an existing ASP.NET Web Application.

  • One involves adding a new Silverlight project to your Web Application
  • The other involves adding an existing Silverlight project to your Web Application.

Here is a description of both options:

  • If you have an ASP.NET Web Project and you want to add a new Silverlight project to it, you can simply right click on the solution file in the Solution Explorer, and choose Add New Project. A dialog appears that allows you to choose to add a Silverlight project to your solution. Select that option and a new Silverlight project will be created and added to the solution. At the same time, code for hosting the Silverlight project will be add to the Web project.
  • If you want to add an existing Silverlight project to your existing ASP.NET Web application, then you should first open the Web project. Now right click on the solution file and choose to Add your existing Silverlight project. Finally, open up the Properties for your Web application, and turn to the Silverlight Applications page.

Summary

In this post you have learned a little bit about how to create a new Silverlight project in Visual Studio 2008. Clearly it is possible to go into more detail to cover special cases. However, the material covered here should hopefully satisfy the needs of most newcomers looking for basic information on creating Silverlight projects. The highlights are as follows. You learned:

  • That you need to install a special add on to enable Silverlight development in Visual Studio
  • How to create a new Silverlight project hosted in a new ASP.NET application.
  • How to add a new or existing Silverlight project to an existing ASP.NET application.

You can download the source for the StarterApp from the LINQ Farm in Code Gallery.

kick it on DotNetKicks.com

Publishing an ASP.NET Web Application in IIS

I had a need to publish a Web Application from Visual Studio 2008 into IIS, rather than into the default Visual Studio Development Server. I already had IIS installed, but I wasn’t quite sure what to do next. Here are some notes that I took on what turned out to be a three step process to publish an ASP.NET Web Application to my IIS Web Server:

  1. Run Visual Studio as an Administrator and go to the Web Page in the Properties for the Web Application. I did that by right clicking on the Properties node in the Solution Explorer. On the Web page in the Properties dialog I switched from “Use Visual Studio Development Server” to “Use IIS Web Server.”
  2. As shown in Figure 1, I then went to the Control Panel and opened this page Control Panel\Programs\Programs and Features and choose:
    1. Internet Information Services
      1. Web Management Tools
        1. IIS 6 Management Compatibility
          1. IIS Metabase and IIS 6 configuration compatibility
  3. Still in the Control, I want to Control Panel\Programs\Programs and Features and choose:
    1. World Wide Web Services
      1. Application Development Features
        1. ASP.NET

 

Steps 2 and 3 are illustrated in Figure 1. Note that IIS Metabase and IIS 6 configuration compatibility and ASP.NET are both selected. When I selected ASP.NET, a number of other options were turned on automatically.

Figure01

After taking these steps, the Create Virtual Directory button in the Web Page of the Properties for my Web Application worked. I was then able to reach the application by typing a URL such as the following into IIS:

  • http://localhost/WebApplication2/

The actual application with my source code remained in the directory where I did my development. The connection between the Virtual Directory and the directory where the application is actually stored can be viewed and configured with the IIS Manager. You can access the Manager here: Control Panel\System and Maintenance\Administrative Tools. In the Connections window on the left of the Manager, browse to Sites\Default Site and click on one of the IIS options such as Authentication. 

In the Actions window on the right of the Manager, choose View Applications, then right click on your application and choose Basic Settings. The dialog shown in Figure 2 appears. You can use this dialog to modify the path to your application. If you then want to switch back to developing your source code in the original location inside Visual Studio, you may have to use the IIS Manager to remove the application.

Figure02

Handling IIS security and set up issues is a subject that I sometimes find a bit challenging, but the information I’ve outlined here solved my problems, and allowed my to proceed with my work.

kick it on DotNetKicks.com
Posted by Charlie Calvert | 7 Comments
Filed under: ,

Silverlight Revisited

I’ve written about Silverlight in previous posts published on this blog. Recently, however, I’ve found my thoughts coming back to this subject. This is hardly unusual: many people are interested in Silverlight.

The reason for the attraction to this technology is not hard to discover. Silverlight allows us to build visually appealing web applications with a sophisticated, well designed programming language such as C#. Though there are now many sophisticated tools for creating web applications, but most of them still depend on fragmented models that force us to integrate multiple, hard to use technologies into a patchwork design that is poorly integrated. Applications built on these models can be hard to debug, and hard to maintain. They also lack the ability to easily support rich interfaces that would be taken for granted in a desktop application.

I’ve spent most of my programming career working in either Delphi or C#, and I have a huge respect for the elegance of these languages, and in the power of object-oriented design to help us break complex problems into manageable, easy to maintain solutions. It is, of course, easy to create poorly designed C# programs. Nevertheless, I believe that C# in particular and Silverlight in general has the capacity, the potential, to support elegant solutions in a way that many web technologies do not.

In short, I’m interested in Silverlight for two reasons:

  1. It allows me to create a rich interface with sophisticated visual techniques including animation.
  2. It provides a thoroughly modern programming model, and a set of rich API’s for performing common programming tasks.

So there, whether one agrees with me or not, is my motivation to revisit Silverlight. Once I had found my inspiration, my next step was to visit the Silverlight site, and download the tools to integrate Silverlight into Visual Studio 2008. The installation worked smoothly on a copy of XP that I had running in a virtual machine. Though I haven’t done it yet, I also intend to download Expression Blend.

Once I had a set of Silverlight tools integrated into Visual Studio, I set about experimenting with them. After a bit, I came up with the application shown in Figure 1. Not bound by such quotidian obligations as having a practical purpose, or a pleasing interface, it didn’t take me long to put this program together. It’s only redeeming feature was that it gave me a chance to experiment with several Silverlight technologies including:

  • XAML and WPF
  • A tool called a StackPanel, which helped me organize the interface, which consists primarily of simple controls such as buttons and text areas.
  • Two different types of Canvases on which I could I draw. 
  • Several different graphical shapes and paths, as well as the Ink technology handed down from Tablet PC.
  • A simple LINQ query.

Silverlight01

Figure 1: A simple Silverlight program, running in the Internet Explorer, which demonstrates how to use several key technologies.

In my next post, I’ll talk some about the code for this application, and describe how its various parts fit together. Overall, I found putting this code together was blessedly simple, and overall quite a bit of fun. At least from what I’ve seen so far, one of Silverlight’s great strengths is its ease of use.

kick it on DotNetKicks.com

Essential LINQ Published

There was a knock on my door this morning. By the time I could make it to the front of the house, the delivery man was gone, but he had left behind a box full red and white books, each with the title Essential LINQ. On the cover was my name, and the name of my good friend Dinesh Kulkarni. This was, of course, a box full of the first copies of my most recent book. They had a arrived at my house on a most propitious date: the first day of spring.

 

 

Holding a copy of my new book in my hands was most pleasurable. Dinesh and I have been working on this text for so many months that I long ago ceased to believe that it would ever actually be published. Instead, I began to think of it simply as a device for stealing my weekends, and for keeping me up late at night when I should be sleeping. And of course, on those rare occasions when I was sleeping, it would bring me awake with a start, my brain repeating the anxious mantra: “The book is not done yet, and chapters are past due!”

We worked hard on this book, and did our best to make it readable. I’m particular proud of the many chapters by Dinesh Kulkarni, the Program Manager who created LINQ to SQL. Dinesh is not only a wonderful human being, but also a brilliant and very hard working engineer. The chapters on LINQ to SQL that he contributed to this book are the best commentaries on the subject that I have ever read. He also contributed a chapter on LINQ to Entities, and an invaluable chapter on LINQ Best Practices. This latter chapter I consider essential reading for everyone who cares about LINQ.

Both Dinesh and I believe in LINQ, and we both wanted to create a text that would be helpful, thorough and easy to understand. It is my hope that we make a good team, and that our skills complement one another. Certainly I enjoyed the opportunity to work closely with Dinesh. We met once a week for a nearly a year to discuss the book. Afterwards, we would often go to lunch, where we would eat vegetarian Indian food and talk about computers, politics, economics, and anything else that came into our head. I always enjoyed those discussions, and consider them one of the great benefits I derived from having the opportunity to help write Essential LINQ.

Here are some links to the book:

kick it on DotNetKicks.com

Community Convergence XLVIII

Welcome to the 48th Community Convergence. The C# team continues to work hard to get out the next version of C#, and to add improvements to the Visual Studio 2010 IDE. Working long, fruitful hours on these rainy Washington State January days and nights, the engineers on our team are doing a great job putting together a set of features that will improve both C#, and the experience C# developers have in the Visual Studio IDE. They are also working to lay the foundation for some big improvements which you will see only after the next version of C# ships.

To keep up with the team's plans, you should:

  1. Continue to follow LINQ
  2. Learn about the Dynamic Features planned for Visual Studio 2010
  3. Learn about the Code Focused IDE features planned for Visual Studio 2010

Here are a few listings that will help you gain deeper insight into all of these important technology:

Videos

Sam Ng

Luca Bolognese

Eric Lippert

Kirill Osenkov

Soma

Matt Warren

 

 

kick it on DotNetKicks.com

10-4 Episode 1: Working with the Visual Studio 2010 CTP

A new series of videos on the Visual Studio 2010 September CTP has been launched. The first episode covers installing and running the CTP, which comes in the form of a VPC.

The video is here.

kick it on DotNetKicks.com

Query Data with Parallel LINQ

This post shows a simple way to write code that takes advantage of multiple processors. You will see that LINQ queries can allow you to side step the difficult tasks normally involved in writing multi-threaded code. To get started, all you need is a little basic knowledge of how to write simple LINQ queries.

The code shown in this post uses a pre-release version of PLINQ called the Microsoft Parallel Extensions to .NET Framework 3.5. When PLINQ finally ships, it will run only on .NET 4.0 or later. The version I'm using that runs on top of 3.5 is for evaluation purposes only. There will never be a shipping version that runs on .NET 3.5.

This LINQ provider is being created at Microsoft by the Parallel Computing team; it is not the work of the C# team that created LINQ to Objects and LINQ to SQL. Here is the website for the Parallel Computing team:

http://msdn.microsoft.com/en-us/concurrency/

At the time of this writing, these extensions were available only in pre-release form. You could download them either as Visual Studio 2008 compatible extensions to .NET 3.5, or as part of the pre-release version of Visual Studio 2010. Since the download sites might change over the coming months, I suggest that you find these resources by going to the Parallel Computing site, or to the Visual Studio site:

http://msdn.microsoft.com/en-us/vs2008

Parallel LINQ, or PLINQ, is only a small part of the Parallel Extensions to the .NET Framework. It is, however, an important part. Since it is a simple and natural extension of the LINQ syntax, I think developers familiar with that technology will find it easy to use.

Consider this code:

var list = Enumerable.Range(1, 10000);

var q = from x in list.AsParallel()
        where x < 3300
        select x;

foreach (var x in q)
{
    Console.WriteLine(x);
}

These lines look nearly identical to the code you have seen in many simple LINQ samples. The only significant difference is the call to AsParallel at the end of the first line. Though we have often used type inference to hide the return type of a LINQ query, I'm going to pause and take a second look at this instance. Rather than returning IEnumerable<T>, this version of PLINQ returns IParallelEnumerable<int>:

IParallelEnumerable<int> q = from x in list.AsParallel() etc….

In the near future, PLINQ queries of this type will probably return ParallelQuery<int>. Because this product is still evolving, it might be simplest to use var, at least during the pre-release phase, and let the compiler choose the type. That way you can save typing, avoid problems with anonymous types, and you need not concern yourself about changes in the API as the product develops. It is almost always appropriate to use var to designate the return type of a LINQ query, and there are only special circumstances when you would do otherwise.

Here are the results from this first PLINQ query:

2
1
3
4
6
512
5
7
513
8
12
514
9
13
515
10
14
516
11
15
517
16
72
518
17

The numbers shown here are in a relatively random order because they are being returned from different threads. It is important to remember that the sequence of values returned by LINQ is not always guaranteed to be presented in a particular order. If Order is important in your code, you can add a call to AsOrdered to the query after the call to AsParallel. Alternatively, you could insert a GroupBy clause to establish the desired ordering. Otherwise developers should assume that the ordering from a PLINQ query will be entirely random

Now that you understand the basics of Parallel LINQ, let’s move on to look at a more interesting example. Improved performance is the main reason to write code that can run in parallel. The program shown in this post uses a timer to demonstrate how PLINQ can improve performance in a program.

Performance improvements become more evident when our code has access to more processors. The code I show here runs faster on a two processor machine, but it really starts to come into its own on a four processor machine. Moving up to even more processors yields more powerful results. Here, for instance, are the results showing an improvement of 1.33 times when using two processors, and almost two times when using 4 processors:

2 Processors = 1.44 x improvement:
Linear: 00:00:13.15
Parallels: 00:00:09.10

4 Processors = 1.96 x improvement:
Linear: 00:00:15.00
Parallel: 00:00:07.68

These tests are being running against pre-release software, so these numbers are almost certain to change before release, and of course different machines will yield different results. Furthermore, the degree of improvement that you see is likely to change depending on the type of algorithm you run, the number of cores on your machine, the architecture of the machine, how many caches there are and how they’re laid out, etc. Though it is rare, some queries show superlinear performance enhancements. In other words, there is a greater than 4x speedup on a 4-core box. An improvement of 2 times, such as the one shown, or even a 3 time improvement, is common.

This sample program is called FakeWeatherData, and it is available for download from the LINQ Farm on Code Gallery. It features a simple LINQ to XML query run against a file with 10,000 records in it. The data I'm querying is not real, but consists of random dates and temperatures generated by a simple algorithm included in the FakeWeatherData program.

The XML file is structured like this:

<?xml version="1.0" encoding="utf-8" ?>
<Samples>
  <Sample>
    <Year>1973</Year>
    <Month>May</Month>
    <Day>15</Day>
    <Temperature>10</Temperature>
  </Sample>
  <Sample>
    <Year>1970</Year>
    <Month>Feb</Month>
    <Day>10</Day>
    <Temperature>14</Temperature>
  </Sample>
  <Sample>
    <Year>1970</Year>
    <Month>Jan</Month>
    <Day>15</Day>
    <Temperature>11</Temperature>
  </Sample>
  ... Many lines of code omitted here
</Samples>

There is also a simple C# class used by the program to encapsulate the data from the XML file:

class WeatherData
{
    public string Year { get; set; }
    public string Month { get; set; }
    public string Day { get; set; }
    public string Temperature { get; set; }
}

The parallel version of the query in the program looks like this:

for (int i = 0; i < NUM_REPS; i++)
{
    var list = (from x in doc.Root.Elements("Sample").AsParallel()
                where x.Element("Year").Value == "1973" &&
                   x.Element("Month").Value == "Apr" &&
                   x.Element("Day").Value == "15"
                select new WeatherData
                {
                    Day = x.Element("Day").Value,
                    Month = x.Element("Month").Value,
                    Temperature = x.Element("Temperature").Value,
                    Year = x.Element("Year").Value
                }).ToList();

}

Accompanying this code is a similar LINQ query that does not use PLINQ

for (int i = 0; i < NUM_REPS; i++)
{
    var list = (from x in doc.Root.Elements("Sample")
                where x.Element("Year").Value == "1973" && 
                   x.Element("Month").Value == "Apr" && 
                   x.Element("Day").Value == "15"
                select new WeatherData
                {
                    Day = x.Element("Day").Value,
                    Month = x.Element("Month").Value,
                    Temperature = x.Element("Temperature").Value,
                    Year = x.Element("Year").Value
                }).ToList();

}

The program queries the data in the XML file first using the Parallel code, then using standard LINQ. By comparing the time it takes each block of code to execute you can get a sense of the relative improvement available through PLINQ. I'll show you how to make such comparisons in just a moment. I will also discuss some tools that will become available to help profile code of this type.

You can see that the PLINQ query contains a call to AsParallel, while the other query does not. Other than that the two queries are identical. The fact that the two queries look so much alike points to a primary strength of PLINQ: very little specialized knowledge is necessary in order to begin using it. This does not mean that the subject is trivial, but only that the barrier to entry is low. This is not the case with most concurrent programming models.

LINQ queries are designed to be read-only, working with immutable data. This is a good model for parallelism, because it makes it unlikely that data will mutate, thereby setting up the potential for a race condition. You should note, however, that PLINQ does nothing to prevent this from happening, it is simply that LINQ is designed to make it unlikely.

Note also that the declarative LINQ programming style ensures that developers specify what they want done, rather than how it should be done. This leaves PLINQ free to ensure that concurrent LINQ queries run in the safest manner possible. If LINQ had been defined more strictly, such that it had to process each element in a certain order, then the PLINQ team would have had a much more difficult task.

The code in both these queries pulls out only the records from the XML file that have their date set to April 15, 1973. Because of deferred execution, the query would not do anything if I did not call ToList(). As a result, I added that call and converted the result into a List<WeatherData>. Though hardly earthshaking in import, these calls ensure that the code actually does something, and thus gives PLINQ scope to take advantage of the multiple processers on your system.

Simple timers are created to measure the difference between the standard LINQ query and the PLINQ query. I've also used a method used in many of Parallel LINQ team's samples for displaying the time elapsed during a test run:

private static void RunTest()
{
    XDocument doc = XDocument.Load("XMLFile1.xml");

    Stopwatch sw = new Stopwatch();

    sw.Start();
    LinqOrdinarie(doc);
    sw.Stop();
    ShowElapsedTime("Ordinaire", sw.Elapsed);

    sw.Reset();

    sw.Start();
    ParallelLinq(doc);
    sw.Stop();
    ShowElapsedTime("Parallels", sw.Elapsed);
}
private static TimeSpan ShowElapsedTime(string caption, TimeSpan ts)
{
    string elapsedTime = String.Format("{0}: {1:00}:{2:00}:{3:00}.{4:00}",
        caption, ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
    Console.WriteLine(elapsedTime, "RunTime");
    return ts;
}

At least with the pre-release version of PLINQ that I've played with, I've found it very useful to set up timers to confirm that PLINQ is actually able to speed up an operation. My record at guessing which code will benefit from running in parallel is not good, and so I find that confirming the effectiveness of the code by explicitly measuring it is worthwhile. You can either use the simple StopWatch class from the System.Diagnostics namespace, as shown here, or else you can use a profiler. Note that a thread aware profiler might ship with some versions of Visual Studio 2010.

I've found that the advantages of concurrent LINQ become more obvious the longer the operation I'm timing lasts. As a result, I've placed the query inside a loop, and added a variable to the program called NUM_REPS. By setting NUM_REPS to a large number, say 500, you can clearly see the benefits that can be accrued when you run LINQ queries in parallel on multiple processors. Note that the first time PLINQ is used, its assembly will need to be loaded, the relevant types will need to be JIT compiled, and new threads will need to be spun up, etc. As a result, many developers see improved performance after they get past the initial warm-up time.

Though it is very easy to get started with PLINQ, there are still complexities inherent in the subject that you need to consider. For instance, PLINQ will sometimes develop a different partitioning scheme for your data depending on whether you are working with an Enumerable or an Array. To learn more about this subject, see the following post from the Parallel Programming team:

http://blogs.msdn.com/pfxteam/archive/2007/12/02/6558579.aspx

The simple PLINQ examples shown in this post should help you get started with this powerful and interesting technology. Parallel LINQ is still in its infancy, but already it provides means of greatly simplifying tasks that are not normally easy to perform.

kick it on DotNetKicks.com
Posted by Charlie Calvert | 23 Comments
Filed under: , ,
More Posts Next page »
 
Page view tracker