Async CTP: TPL Dataflow - Buffering and Combining Data

In our previous TPL Dataflow post we introduced the concept of linking TPL Dataflow blocks together in a processing chain. The example we used was effective in illustrating the point. It was a simple, yet not very practical example showing how we can link multiple TBL Dataflow blocks into a network for propagating and processing data to get to an end result.

Let's consider another example that illustrates a more practical scenario where we have data coming in from multiple sources that needs to be combined, transformed and then propagated out to an end point such as user interface. But first we'll need introduce two additional TPL dataflow blocks that will help illustrate these concepts. These two blocks are BufferBlock<T> and JoinBlock<T>.

BufferBlock<T> is a dataflow block for buffering data from a source and propagating it out to a target. It receives incoming data from some source and buffers it up as output to be consumed by some other entity down the propagation chain. JoinBlock<Tin, Tout> accepts two inputs and joins them together into tuples, buffering them as output to be consumed by some other entity in the propagation chain. By themselves, BufferBlock<T> and JoinBlock<Tin, Tout> are not very interesting, but when combined with other TPL Dataflow blocks they can be used to create complex dataflow networks for developing robust messaging based applications that process data in an asynchronous and concurrent fashion.

Let's consider a scenario where we have integer data coming in from two different sources that we need to add together and present to a user input. To accomplish this we'll use two BufferBlock<T> blocks representing the two data sources. We'll combine the inputs from the two data sources into tuples using JoinBlock<Tin, Tout> so that they can be added together further down the chain. We'll use a TransformBlock<Tin, Tout> to add the items in each tuple, and finally we will use ActionBlock<T> will present the sum to the console. The dataflow network for this scenario would look something like the diagram show below.

image

The code for this is very straight forward. We'll configure each block, link them together according to the dataflow graph pictured above and then post the data to each of the BufferBlock<T> blocks which in turn will be propagated through the data network where it will be transformed and presented to the console. Here's the code

 

class Program
{
    static void Main(string[] args)
    {
        var buf1 = new BufferBlock<int>();
        var buf2 = new BufferBlock<int>();
        var join = new JoinBlock<int, int>();
 
        var transform = new TransformBlock<Tuple<int, int>, string>(t =>
        {
            return string.Format("{0} + {1} = {2}", t.Item1, t.Item2, t.Item1 + t.Item2);
        });
 
        var action = new ActionBlock<string>(s =>
        {
            Thread.Sleep(500);
            Console.WriteLine(s);
        });
 
        buf1.LinkTo(join.Target1);
        buf2.LinkTo(join.Target2);
        join.LinkTo(transform);
        transform.LinkTo(action);
 
        for (int i = 0; i < 20; i++)
        {
            if (i % 2 == 0)
                buf1.Post(i);
            else
                buf2.Post(i);
        }
 
        Console.WriteLine("Posting Complete!");
        Console.ReadLine();
    }
}
 

Here's the output:

image

As you can see, the data was posted to the buffer blocks immediately, indicated by the Posting Complete message. Then processing kicked in, are buffered data was combined into tuples, transformed and then presented the result to the console.

In this series of posts we introduced several of the concepts being exposed in the next version of the Visual Studio .NET and the .NET Framework. I personally think these are some pretty cool capabilities that we can look forward to. You can start learning about them today by downloading the Async CTP. The examples in these posts will work with Version 3 of the Async CTP released in October 2011 available at http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=9983, as well as the September 2011 release of Visual Studio 11 Developer preview available at http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=27543.


Posted by: Kyle Libbert
Posted on: 2/3/2012 at 12:17 PM
Categories: .NET | Async | Parallel Computing
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Async CTP: TPL Dataflow - Linking Blocks Together

In our previous posts on TPL Dataflow we talked about ActionBlock<T> and TransformBlock<Tin, Tout>, two dataflow blocks exposed in the TPL Dataflow library that allow you to process message based data asynchronously in a parallel manner. These two blocks, in and of themselves, are quite useful, but there are additional blocks, and additional capabilities available in TPL Dataflow that we can take advantage of that you may want to concern yourself with.

One of the most important aspects of the TPL Dataflow library is the ability to link multiple blocks together. Dataflow blocks can be chained together to form arbitrary dataflow networks where the output from one block can be exposed as inputs to other blocks, or where the output from many different blocks needs to be joined into a single output and exposed to one or more blocks further down in the processing chain. There are many scenarios in which this can be useful, such as a stock hit application where data about stocks is coming in from multiple sources, or when acquiring data from a biometric feedback device where you might be collecting data from multiple channels to analyze and report on different aspects of biometric data from a patient such as blood pressure, heart rate or ECG.

Let's take a look out how we can use TPL Dataflow to solve these types of problems. TPL DataFlow has the ability to link the input of a target block to the output of a source block via the ISourceBlock.LinkTo() method that is available on every source block type. Building on the examples from our previous posts where we described ActionBlock<T> and TransformBlock<Tin, Tout>, we'll take advantage of the ISourceBlock.LinkTo() method to link TransformBlock<Tin, Tout> block's output to ActionBlock<T> block's input.

In this example we'll create an ActionBlock<T> that will accept incoming data, sleep briefly and then output the incoming data to the console. We'll also create a TransformBlock<Tin, Tout> that will accept incoming integer data, transform that data by doubling it and then place the transformed data on the output queue for further processing. Finally we'll link the TransformBlock<Tin, Tout> output to the ActionBlock<T> input using the LinkTo() method of the TransformBlock<Tin, Tout> and then post some data. Here's the code:

 

class Program
{
    static void Main(string[] args)
    {
        var action = new ActionBlock<int>(i =>
        {
            Thread.Sleep(500);
            Console.WriteLine(i);
        });
 
        var transform = new TransformBlock<int, int>(i => i * 2);
 
        transform.LinkTo(action);
 
        for (int i = 0; i < 10; i++) transform.Post(i);
 
        Console.WriteLine("Posting Complete!");
        Console.ReadLine();
    }
}
 

Here's the output:

image

As you can see, the data was posted to TransformBlock<Tin, Tout>, multiplied by 2, and then propagated to ActionBlock<T> via the ISourceBlock.LinkTo link where it was presented to the console.

This was a simple to illustrate the concept of linking the output of one block to the input of another in a processing chain. In our next post we'll take this a step further by showing you how we can buffer our output and consume that buffered output further down in the processing chain using the BufferBlock<T> block. We'll also take a look at out we can consume data from multiple sources and combine them using JoinBlock<Tin, Tout> for further processing later in the processing chain.


Posted by: Kyle Libbert
Posted on: 2/3/2012 at 12:08 PM
Categories: .NET | Async | Parallel Computing
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Async CTP: TPL Dataflow - TransformBlock<Tin, Tout>

In our previous TPL Dataflow posts we introduced the TPL Dataflow Library and showed you some of the capabilities of ActionBlock<T>, a dataflow block available in TPL Dataflow that allows you to buffer up messages and process those messages concurrently. We also took a slight detour and discussed how we can control the lifetime of our tasks through some of the completion mechanisms available via the IDataflowBlock interface. In this post we'll continue the main Async CTP TPL Dataflow discussion and introduce another TPL Dataflow block called TransformBlock<Tin, Tout>.

TransformBlock<Tin, Tout>, for those familiar with LINQ, is somewhat similar to Select in that it takes an input, transforms that input in some manner, and then produces an output. Like ActionBlock<T>, a TransformBlock<Tin, Tout> buffers all of its input data and processes that input data asynchronously using a function that we provide. By default TransformBlock<Tin, Tout> processes its data sequentially with a MaxDegreeOfParallelism equal to 1. This of course can be controlled using ExecutionDataflowBlockOptions.

The interesting thing to note about TransformBlock<Tin, Tout> is that in addition to receiving buffered input and processing it, TransformBlock<Tin, Tout> will take all of its processed output and buffer that as well. Are you starting to see a theme here?

Let's take a look at an example using TransformBlock<Tin, Tout> that transforms each integer into its double.

 
class Program
{
    static void Main(string[] args)
    {
        var transform = new TransformBlock<int, int>(i => i * 2);
        for (int i = 0; i < 10; i++) transform.Post(i);
        Console.ReadLine();
    }
}

Not a very interesting example, really. We provided a Func<> to TransformBlock<Tin, Tout> that returns each input multiplied by 2. As we expect the data is posted to the block and buffered for processing. TransformBlock<Tin, Tout> executes the provided Func<> and the results are then buffered for further processing by some other mechanism in our application. But how do we know that our input and output are being buffered? Let's take advantage of the debugger and find out for sure.

Using the Visual Studio Async CTP create a console app containing the following code and run it under the Visual Studio Debug configuration.

 
class Program
{
    static void Main(string[] args)
    {
        var transform = new TransformBlock<int, int>(i =>
            {
                Console.WriteLine(i * 2);
                return i * 2;
            });
 
        for (int i = 0; i < 10; i++) transform.Post(i);
        Debugger.Break();
        Thread.Sleep(1000);//Give the TransformBlock some time to process the input
        Debugger.Break();
        Console.ReadLine();
    }
}
 

Notice that the Visual Studio debugger stopped at the Debugger.Break statement. Now hover over the transform instance variable and you'll see that the current InputCount showing that immediately after posting all of the data 10 items have been buffered for processing.

clip_image001

Also note that the OutputCount shows zero items because we broke into the debugger just prior to processing the data.

Now continue executing in Visual Studio until the second Debugger.Break statement and hover your mouse pointer over the transform instance variable again to verify the current state of TransformBlock<Tin, Tout>. You can see that the OutputCount is now equal to 10, indicating that the processing occurred and that 10 items were processed and queued up in the output buffer.

clip_image003

Still not a very interesting example. How do we know that each input was actually doubled and placed into the output queue? So let's make sure that TransformBlock<Tin, Tout> did indeed process our data. Run the example again until the debugger breaks at the second Debugger.Break statement. This time hover over the transform instance variable and drill down into the instance to the OutputQueue, and notice that it indeed contains the double of each of our inputs.

clip_image004

There are variety of capabilities available on these TPL Dataflow blocks that further enhance your ability to process data using parallel patterns. We've only scratched the surface here with the introduction of the TPL Dataflow ActionBlock<T> and TransformBlock<Tin, Tout> along with some of their capabilities. In our next post we'll introduce additional features and capabilities of TPL Dataflow, including the ability to link different dataflow blocks together to create arbitrary dataflow networks that asynchronously propagate data through a series of processing steps to get our data into its desired form.


Posted by: Kyle Libbert
Posted on: 12/27/2011 at 3:20 PM
Categories: .NET | Async | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Async CTP: Task Completion in TPL Dataflow

In our previous posts we introduced the concept of TPL Dataflow and even showed how you can take advantage of ActionBlock<T> to process incoming data in parallel. We also showed how you can control the degree of parallelism applied in a parallel dataflow through the use of the ExecutionDataflowBlockOptions MaxDegreeOfParallelism property. In this post we'll introduce the concept of task completion in a parallel dataflow.

Often times when dealing with these types of data loads in your applications you may want to post a large amount of asynchronous data for processing and then be notified when that processing has completed. We can do this easily in TPL DataFlow because each TPL Dataflow block has a lifetime, and each block type exposes mechanisms that allow us to monitor and control that lifetime such that we can wait for the tasks to complete all of their processing, or be notified when they have completed their processing. This can be accomplished via mechanisms on the Completion property exposed by ActionBlock<T>. The Completion property is a property hanging off of one of the core interfaces implemented by all TPL Dataflow blocks called IDataFlowBlock. As such, all TPL Dataflow blocks, including ActionBlock<T> expose the IDataFlowBlock.Completion property. Using the IDataflowBlock.Completion.Wait() statement we can wait for processing to complete after we've submitted all of our data.

Let's illustrate this in an example. In this example we'll use IDataflowBlock.Completion.Wait to wait for processing to complete. One interesting thing to note is that the Wait method will wait forever because it will never know that ActionBlock<T> is no longer receiving data. To circumvent this, we can tell ActionBlock<T> when we've finished posting data by issuing ActionBlock<T>'s base interface IDataflowBlock.Complete method. This will notify ActionBlock<T> that it will never be giving it more data, so once it's finished processing its queue it can shut itself down, thus notifying us that it has completed processing by releasing the Completion.Wait() call that our main thread is blocking on.

 
class Program
{
    static void Main(string[] args)
    {
        var action = new ActionBlock<int>(i =>
        {
            Thread.Sleep(500);
            Console.WriteLine(i);
        }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 });
 
        for (int i = 0; i < 10; i++) action.Post(i);
        action.Complete();
        Console.WriteLine("Posting Complete!");
        action.Completion.Wait();
    }
}

clip_image002

Besides IDataflowBlock.Complete and IDataflowBlock.Completion, IDataflowBlock also provides a Fault completion mechanism as well. Say for instance we are preprocessing and validating the incoming data before we queue it to our ActionBlock<T> in the example above. If we encounter invalid data during processing we may want to issue a IDataflowBlock.Fault() telling the ActionBlock<T> that we've encountered an invalid state and that is should discontinue processing.

In our next post we will pick up where we left off in our previous post and describe additional dataflow blocks available in TPL Dataflow.

Note: If you want to try these examples out make sure to add a reference to the new System.Threading.Tasks.DataFlow library in your project. Keep in mind; by default the Visual Studio Async CTP bits will be installed in your My Documents library under Microsoft Visual Studio Async CTP, so make sure to browse to that location under the Samples folder to add a reference to the System.Threading.Tasks.DataFlow assembly.


Posted by: Kyle Libbert
Posted on: 12/27/2011 at 3:11 PM
Categories: .NET | Async | TPL Dataflow | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Async CTP: TPL Dataflow - ActionBlock<T>

In our previous post, Async CTP - TPL DataFlow, we introduced TPL Dataflow a new library that was released for preview as part of the Microsoft Visual Studio Async CTP. In that post we introduced and described the capabilities that that library provides for building data parallelism into your .NET applications. In this post and the next several posts, we'll expand further on the TPL Dataflow capabilities and provide some examples for using the TPL Dataflow blocks in your applications.

There are several different types of dataflow blocks in the TPL Dataflow library that let you solve a variety of processing scenarios (Join, Transform, etc). One such type is ActionBlock<T>. If you recall from our previous post (Async CTP - TPL DataFlow) where we introduced TPL Dataflow, ActionBlock<T> is an ISourceBlock that accepts and buffers incoming data and performs some action on that data.

You provide ActionBlock<T> with a delegate that will act on the data being posted to it. That delegate executes on every piece of data, in order, that is provided to ActionBlock<T>. The data is posted to ActionBlock<T> via a Post method. The Post method gives ActionBlock<T> data which it will buffer up and internally start spinning tasks to process that data as fast as it can. We can bet illustrate this with an example.

The example below illustrates configuring an ActionBlock<T> with a delegate that simply writes integers out to the console in the order received. Outside ActionBlock<T> is a simple loop that posts integers to it for processing. To make it a little bit easier to see what's going if you try this yourself, we'll introduce a Thread.Sleep so that we can see when and in what order things complete.

 
class Program
{
    static void Main(string[] args)
    {
        var action = new ActionBlock<int>(i =>
            {
                Thread.Sleep(500);
                Console.WriteLine(i);
            });
 
        for (int i = 0; i < 10; i++) action.Post(i);
        Console.WriteLine("Posting Complete!");
        Console.ReadLine();
    }
}
 
clip_image002

There are a couple of interesting things to note from the output. First, you can see that almost immediately the 10 integers were posted to ActionBlock<T>, denoted by the "Posting Complete!" message displayed to the console. The second and more important thing is that the data is being processed in order. This is a key feature of TPL DataFlow. By default, ordering is maintained. This also means that while data is being processed asynchronously, it is also processed sequentially, guaranteeing the order of processing. In other words the data is being processed with a maximum degree of parallelism of 1. What this is telling us is that, in this scenario, the default behavior is not actually to process the input in parallel, but to process it in order, thus guaranteeing the order of processing. Since processing in parallel means processing concurrently and most likely, if not definitely means that things could get processed out of order.

That said there are certain processing scenarios where we are willing to give up on some of these ordering guarantees. ActionBlock<T> is configurable via a mechanism known as ExecutionDataflowBlockOptions that control the degree of parallelism that occurs. The ExecutionDataflowBlockOptions type is essentially an options bag for controlling how ActionBlock<T> will act. One of the options available on ExecutionDataflowBlockOptions is MaxDegreeOfParallelism which, among other things, allows you to specify the maximum number of parallel tasks to execute concurrently on the incoming data. By default this option is set to 1, thus guaranteeing the order of processing.

In this next example we illustrate this by increasing the MaxDegreeOfParallelism to 4. Here the task scheduler will create up to 4 parallel tasks to concurrently process the incoming data.

 
class Program
{
    static void Main(string[] args)
    {
        var action = new ActionBlock<int>(i =>
            {
                Thread.Sleep(500);
                Console.WriteLine(i);
            }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 });
            
        for (int i = 0; i < 10; i++) action.Post(i);
        Console.WriteLine("Posting Complete!");
        Console.ReadLine();
    }
}
clip_image004

From the output we can see that the data was processed out of order due to the fact that ActionBlock<T> scheduled multiple tasks concurrently to process the incoming data. It is important to note that the MaxDegreeOfParallelism option is not specifying the actual number of tasks to use to process the data, but it is setting a limit on the number of tasks to use. The actual number of tasks used is controlled by the task scheduler, which incidentally can be changed via ExecutionDataflowBlockOptions. There are a variety of ExecutionDataFlowBlockOptions available for controlling how the TPL Dataflow blocks will work. We'll try to get to those in future posts.

ActionBlock<T> is just one example of data flow that exists in TPL Dataflow. However, there are others that further compliment the ability to easily perform parallel processing in your applications. Look for future postings that further describe these blocks as well as the other parallel computing capabilities of the TPF Dataflow library. In our next post we'll diverge slightly and talk about task completion and how we can control that use mechanisms provided to you by IDataflowBlock.


Posted by: Kyle Libbert
Posted on: 12/27/2011 at 2:48 PM
Categories: .NET | Async | TPL Dataflow
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Async CTP: Intro to TPL DataFlow

Many of you are probably already familiar with the parallel processing capabilities offered by the Task Parallel Library (TPL) that was first introduced in the .NET Framework 4. In .NET 4 TPL provided some core building blocks and algorithms for doing parallel computing in your .NET applications. Now that the development for the next version of the .NET platform is well under way, it is no surprise that Microsoft is looking for new ways to improve upon a good thing. One such update which should make the final cut is yet another way for developers to build highly responsive code using the new Async capabilities of .NET (see Andrew Troelson's Async CTP Anyone?), currently available as a community technology preview known as the Async CTP. One component of the Async CTP is TPL Dataflow, a library for doing agent/actor based data processing using parallel techniques.

The TPL Dataflow library was first released for preview as part of the Microsoft Visual Studio Async CTP, and it is also available in a separate TPL Dataflow CTP, both of which you can download from http://msdn.microsoft.com/vstudio/async. Both the Async CTP and TPL Dataflow CTP bits can be installed and used with Visual Studio 2010 SP1.

Typically when you did parallel programming with .NET 4 you were being proactive. It was usually the case that you had some data and you wanted to perform some computation on that data. For example, you may have a range of data that you wanted to perform some computation on, or you might need to filter your data in such a way that it was useful to you in your application. To solve these problems in .NET 4 with the Task Parallel Library you might have used Parallel.For or Parallel.Foreach, or possibly even a PLINQ query to iterate through the data and take advantage of the parallel constructs provided to you by TPL. In all these cases is was typically data first, then computations on that data later using primitives for tasks and data parallelism provided to you by the Task Parallel Library. What was missing was the ability to be reactive. Essentially the ability to setup your computation framework first, and then react to the data as it is coming in.

This reactive method of processing data is commonly referred to as dataflow parallelism. Essentially what you're doing is creating computational networks through which data can flow. Agent-based and actor-based message passing patterns like the producer/consumer pattern follow this reactive model. With the introduction of TPL Dataflow you will be able to use the parallel programming paradigms in your own .NET applications to build reactive dataflow networks. This is not to say that you couldn't have solved these problems in .NET 4 using Task Parallel Library, however it would have involved quite a bit of code to manage buffering data, scheduling tasks and dealing with the inter-process communications required to perform the work. The TPL Dataflow library gives you a lot of the primitives that you need to solve these problems out of the box without having to worry about the minutia required to implement such architectures.

So what is TPL Dataflow? Essentially it is a parallel processing library that exposes primitives for doing in-process messaging passing and processing. TPL Dataflow provides a set of agents, commonly referred to as dataflow blocks, or simply blocks, that contain the infrastructure required to buffer and process your data in an asynchronous and parallel manner. TPL Dataflow provides the infrastructure for being able to build data parallelism into your applications.

At the core of the TPL Dataflow library is its interface hierarchy, pictured below. These interfaces describe the behavior of a dataflow block. At the very top of the hierarchy is IDataflowBlock, defining contract for dealing with the lifetime of a dataflow block. Below IDataflowBlock are three sub-interfaces that define contracts for blocks that can be a source of data, blocks that can be a target for data, and blocks that can be both a source and target for data. ISourceBlock represents a source of data, defining a contract for buffering and receiving data. ITargetBlock represents a target for incoming data, defining a contract for buffering and passing data. Finally IPropagatorBlock represents a block that can be both a source and a target for data, defining a contract for receiving data from sources, possibly transforming that data and propagating the result on to other targets.

clip_image002

With these interfaces you can develop your own blocks to build your own custom dataflow networks, but there are also several built in blocks for the most common scenarios like buffering and propagation of data, acting on data, and even blocks for joining data from multiple sources then buffering and presenting the result to a target.

For buffering and propagation of data TPL Dataflow provides the following blocks:

BufferBlock<T> - buffers incoming data and delivers that data to a target in an asynchronous and parallel fashion.

WriteOnceBlock<T> - accepts one piece of data and delivers that piece of data in a broadcast fashion to all target blocks interested in that piece of data.

BroadcastBlock<T> - accepts multiple pieces of data, buffering them as they arrive and broadcasts each piece of data to all interested target blocks.

For acting on incoming data TPL Dataflow provides the following dataflow blocks:

ActionBlock<Tin> - an ISourceBlock that accepts and buffers incoming data and performs some action on that data.

TransformBlock<Tin, Tout> - an IPropagatorBlock that accepts and buffers incoming data, executes some function on that data and then buffers the output to be consumed by a target.

TransformManyBlock<Tin, Tout> - very similar to TransformBlock, however the relationship to its targets is one-to-many. It buffers and transforms incoming data, then buffers and makes that data available to multiple targets.

For joining and grouping data TPL Dataflow provides the following dataflow blocks:

BatchBlock<T> - An IPropagatorBlock that accepts and buffers incoming data and groups that data into batches (arrays).

JoinBlock<T1, T2> - Accepts and buffers data from two different source blocks, combines data from each source into tuples, then buffers and makes those tuples available to a target.

BatchedJoinBlock<T1, T2> - a combination of BatchBlock and JoinBlock that groups pairs of collections of incoming data into tuples of those collections, buffering and presenting that data as output to a target.

As you can see TPL Dataflow provides you with some significant capabilities for developing parallel dataflow capabilities into your own applications without having to reinvent the infrastructure to do so. This was a quick look at the TPL Dataflow and the interface hierarchy upon which it is build, as well as some of the built in capabilities for building applications that incorporate data parallelism. Watch for future posts where we'll look at some of these built in mechanisms along with examples demonstrating how you can get started using TPL Dataflow.

If you are interested in looking at the current state of this new technology, here are some helpful links: 


Posted by: Kyle Libbert
Posted on: 12/15/2011 at 9:21 PM
Categories: .NET | Async | Parallel Computing | TPL Dataflow | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Silverlight?

So, if you are currently following the stories of Silverlight, Windows Runtime / Metro and .NET 4.5, you may have some confusion regarding where Silverlight sits in the land scape of Microsoft development. Well, you are not alone!  Part of the problem (as always) is the ?InterWeb?.  Do a web search on some phrase such as ?Is Silverlight Dead? and you will get numerous conflicting answers.

In a nutshell, it does seem that Microsoft is putting it?s money in HTML 5 as the champ of interactive web content. Furthermore, given that the forthcoming Windows 8 OS (and the related Metro style apps) are built using a whole new technology stack,  it does seem that the Silverlight we know today may have a limited scope (and possibly a limited lifetime).

However!  The spirit of Silverlight will live on.  As you might know, a Metro style app is constructed using the same core tools .NET programmers are already familiar with. You will build such apps using a managed language (C# or VB) or via C++. As well, XAML (or HTML 5) will be used to build out your overall UI. So the *good* news is, developers who are currently using Silverlight (or WPF for that matter) will be in a very good position to build Metro apps when Windows 8 is released.

You?ll use Visual Studio and Blend, reference assemblies and import namespaces, and build away.

As far as Silverlight proper, this will still be a useful tool for some time to come (if you ask me).  The first obvious reason is that all of IT is not going to rush into installing Windows 8 across the workplace (regardless of what we geeks might desire). Computers running Windows XP or Windows 7 will still be able to display Silverlight applications as expected. As well, if one boots up the traditional desktop from Windows 8, and launches the ?traditional? set of web browsers, Silverlight apps should run as advertised.

Even though the overall scope of Silverlight may be changing, it is worth pointing out that Silverlight 5.0 (which has recently been released) ships with numerous bells and whistles. As a quick rundown:

  • Implicit data templates
  • ClickCount support
  • Improved styles
  • Custom markup extensions
  • An improved 3D graphics API

It should not be too surprising that many of these ideas will migrate (in a slightly different manner) to Metro and .NET 4.5.

So, if you are currently building Silverlight apps, check out the new features offered by 5.0.  If you are not currently building Silverlight apps, you might wish to at least read over the key features here, to get a better idea of what life may have in store for the future.


Posted by: Andrew Troelsen
Posted on: 11/28/2011 at 10:22 AM
Categories: Silverlight | .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

UML and Visual Studio? Yes please!

Visual Studio has supported visual class designers for quite some time.  As useful as these features are, the one problem is that the diagram produced is *not* UML proper, but a ?UML-like? notation.

Awhile back, Microsoft released a Visual Studio Feature Pack for MSDN subscribers which allows you to generate proper UML diagrams (of various flavors). You can download this feature pack by clicking on the ?Visual Studio 2010 Feature Pack 2? link at this web site.

Once you have installed the feature pack, you will be able to:

  • Use the Generate Code command to generate skeleton code from elements on UML class diagrams. You can use the default transformations, or you can write custom transformations to translate UML types into code.
  • Create UML class diagrams from existing code.
  • Explore the organization and relationships in C, C++, and ASP.NET projects by generating dependency graphs.
  • Import elements from UML sequence diagrams, class diagrams, and use case diagrams as XMI 2.1 files that are exported from other modeling tools.
  • Create links and view links from work items to model elements.
  • Create layer diagrams from C or C++ code and validate dependencies.
  • Write code to modify layer diagrams and to validate code against layer diagrams.

Just to give a taste, assume you have a current C# project, and which to generate some UML class diagrams. First, from the Architecture menu option, select New Diagram.  From here, you can pick from any of the following:

image

Assuming you select a new UML Class Diagram, you can open the Architecture Explorer window, and drag types onto the created visual designer:

image

The resulting UML is then generated by the tool:

image

Another great feature of this feature pack is the ability to generate dependency graphs of your code. For example, if you were to select the Architecture | Generate Dependency Graph menu option, you will find a diagram such as the following:

image

There is much more you can do with this feature pack, and if you have an MSDN subscription ID, I?d say it is certainly worth a download!

Happy coding.


Posted by: Andrew Troelsen
Posted on: 11/14/2011 at 2:09 PM
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Net Debugging Tool Hawkeye

There are numerous WinForm applications that still exist throughout our organizations.  As we maintain and migrate to these applications it's beneficial to have tools that help increase our development productivity, and minimize the pain we experience trying to locate controls in our complex business applications. Hawkeye is a tool that you should have close at hand when you need target specific WinForm controls on the fly.  Whether your controls are static or dynamic, Hawkeye will help you peel the onion of obscurity in your layered application.  And as a codeplex project, Hawkeye should meet your budget needs. 

Having used this tool on various projects this tool has been most beneficial when needing to:

  • adjust visual control properties on the fly
  • locating object information on complex forms.

Unfortunately the documentation for Hawkeye is somewhat limited so hopefully this will help get you started:

Get Hawkeye

  1. Download the Hawkeye tool (http://hawkeye.codeplex.com/): There are two flavors on the download page, the naming convention is the N2 is for .NET 2.0 based applications and N4 is for the .NET 4 based applications make sure to get the right one for you.
  2. The download is a zip file so unzip those files to your directory of choice
  3. Because there is no installation I would recommend creating a shortcut and place it somewhere within quick reach.

Interface Basics

in the image below shows the common controls and information areas of Hawkeye that you will want to be aware of:

Hawkeye_CommonControls

**Important to note if you are debugging a .NET 4 application to allow Hawkeye to inject itself into the application process of your application you will need to add the element 'loadFromRemoteSources' to your app.config file (see following example).  There are security related issues with this so be sure to remove that element when deploying your applications.  For more specific information see the following link (http://msdn.microsoft.com/en-us/library/dd409252(VS.100).aspx)

   1: <configuration>
   2:   <runtime>
   3:     <loadFromRemoteSources enabled="true "/>
   4:   </runtime>
   5: </configuration>

Using Hawkeye:

  1. start your application with a debug configuration.  For most of us developers this is pressing (F5) in our Visual Studio Environment. 
  2. Once your application loads start Hawkeye
  3. Drag the Target symbol from Hawkeye onto the control you want to target HawkeyeTarget
  4. The control information should appear. 

The following image shows a simple form with Hawkeye displaying the control information:

HawkeyeInAction

 

Tips:

  • Navigation
    • use properties to navigate through collections this is accomplished by right clicking the desired property name and click select. 
    • There are <back> <forward> <up> arrows to navigate to properties that you have previously selected and the parents of the currently selected property.
  • Highlighting the current selected object by clicking the Highlight Current Target button
  • Model windows can prevent you from selecting a new target so use the <control> + <shift>+ <R> buttons to release Hawkeye to select a new target.  Sometimes you may need to start another instance of Hawkeye to enable selecting a model window target.
  • Changing property values will result in immediate feedback which can be very helpful in aligning controls
  • Explore some of the other options and see the valuable information that this tool is able to provide you.

I hope this posting has provided you a basic understanding of the Hawkeye tool.

~Enjoy

Hawkeye CodePlex site http://hawkeye.codeplex.com.


Posted by: Jim Rouse
Posted on: 10/22/2011 at 2:01 PM
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Modifying Generated Code in a Coded UI Test

Intro

This is part 8 in a series of posts on creating and maintaining Coded UI tests with Multiple UI maps. My intent here is to give a little more detail to help those new to Visual Studio.

Part 1: Creating a new Coded UI solution

Part 2: Adding a New UI Map

Part 3: Modifying an Existing Coded UI Map

Part 4: Adding a UI Map to the TestRunUtility

Part 5: Assembling the test

Part 6: Changing Recorded Methods

Part 7: Deleting actions when recording with the Coded UI Test Builder

Part 8: Modifying Generated Code

Credits

This technique is an extension of the technique found in the following links by Anu , a Program Manager in the Visual Studio ALM Test Tools group and the MDSN documentation. http://blogs.msdn.com/b/anutthara/archive/2010/02/08/scaling-up-your-cuit-ui-automation-for-real-world-projects.aspx

http://blogs.msdn.com/b/anutthara/archive/2010/02/10/walkthrough-using-multiple-coded-ui-maps-in-test-automation.aspx

http://msdn.microsoft.com/en-us/library/ff398056.aspx

 

Modifying Generated Code

I mentioned that we should not edit code found in the <Page>Map.Designer.cs file. What should we do if we want to customize our code (we will make our AssertQuantity more robust)? Double click on the uitest file that contains the code you want to modify. In the UI map editor highlight the method you want to change -> click the Move Code button -> click the save all button or ctrl + shift + S.

Now double click the ShoppingCartPageMap.cs and notice we have code. We can safely edit the code now without fear that the code generator will overwrite our changes.

image

Here is the AssertQuantity method before our changes:

public void AssertQuantity()
        {
            #region Variable Declarations
            HtmlEdit uIQuantityEdit = this.UIHomeTailspinToysWindWindow.UIHomeTailspinToysDocument.UIQuantityEdit;
            #endregion

            // Verify that 'Quantity' text box's property 'Text' equals '1'
            Assert.AreEqual(this.AssertQuantityExpectedValues.UIQuantityEditText, uIQuantityEdit.Text);
        }

We are going to modify the method signature and the highlighted expected value to accept a parameter rather than the constant 1 (so that we can validate quantities other than 1).

The altered code looks like this:

        public void AssertQuantity(string expectedValue)
        {
            #region Variable Declarations
            HtmlEdit uIQuantityEdit = this.UIHomeTailspinToysWindWindow.UIHomeTailspinToysDocument.UIQuantityEdit;
            #endregion

            Assert.AreEqual(expectedValue, uIQuantityEdit.Text);
        }

Once we make this change, our test case will no longer run because our call to AssertQuantity does not pass in a parameter.

image

 

To fix that we need to pass in the value we expect in the Quantity text box, a ?1?.

The altered code will look like this:

[TestMethod]
        public void AddOneCoffeFlyerToCartTest()
        {
            TestRunUtility trUtility = new TestRunUtility();
            try
            {
                trUtility.HomePage.NavigateToTailspinToysSite();
                //On the home page click the Model Airplanes button
                trUtility.HomePage.NavigateToModelAirplanes();
                //From model airplane page, click the view fourth coffee flyer button
                trUtility.ModelAirplanePage.ViewFourthCoffeeFlyer();
                //From the fourth coffee Flyer details page, click add to cart
                trUtility.FourthCopyFlyerDetailsPage.AddFourthCoffeeFlyerToCart();
                //We should be at the shopping cart now
                //Validate the quantity
                trUtility.ShoppingCartPage.AssertQuantity("1");
                //Clean out the cart
                trUtility.ShoppingCartPage.RemoveItemFromCart();

            }
            finally
            {
                //close the browser
                trUtility.HomePage.CloseBrowser();
            }
        }

For fun, change the ?1? to a ?2? . Now when you run the test (not debug), we should see the test fail and we should still see the browser close which is the behavior we want.


Posted by: Tim Star
Posted on: 8/26/2011 at 3:08 PM
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed
Contact Us 651-994-8558 1-800-866-9884
Home | Training | Curriculum | Course Finder | Schedule | Enroll | Twin Cities Java User Group | Consulting | Foundation | Jobs | About Us | Our Story | Press Room | Instructors | President | Map & Directions | Sitemap

Java Training | JSF / Struts / Spring / Hibernate Training | Java Power Tools Training | .NET 4.0 & Visual Studio 2010 Training | .NET 3.5 and Visual Studio 2008 Training | .NET 2.0 and Visual Studio 2003 Training | Prism / MVVM / MEF Training | Microsoft Web Development Training | Cloud Computing Training | Ajax / Web Services / XML Training | Groovy and Grails Training | SQL Server 2008 Training | SQL Server 2005 Training | Mobile Development Training | SharePoint 2010 Training | SharePoint 2007 Training | Agile, Process, Analysis & Design Training | Arch/Design Patterns Training | Microsoft Official Curriculum Training | Web Development Training | Ruby Training | Rational Application Developer (RAD) Training | WebSphere Application Server Training | WebSphere Portal Training | WebLogic Training | Boot Camp Training | Project Management Training | C++ Training | Metro / WinRT / Windows 8 Development Training | Retired

Intertech delivers training on-site and virtually serving cities including Phoenix, AZ | San Francisco, CA | Los Angeles, CA | San Diego, CA | San Jose, CA | Washington, DC | Chicago, IL | Orlando, FL | Boston, MA | Duluth, MN | Minneapolis St. Paul, MN | Rochester, MN | Raleigh-Durham, NC | New York, NY | Philadelphia, PA | Austin, TX | Dallas, TX | Houston, TX | Seattle, WA.