imageIn this post, I’ll consolidate few posts on four .NET libraries/frameworks, that’ll help you write better apps

MEF or Managed Extensibility Framework - System.ComponentModel.Composition

MEF or Managed Extensibility Framework is cool. Firstly, it allows you to decouple your components pretty easily. Secondly, it supports various component discovery scenarios, and enables you to write better frameworks.

Reactive Extensions and LINQ To Events – System.Reactive

Reactive Extensions will soon become the de-facto for writing asynchronous code in a declarative manner .NET Rx gives greater freedom to compose new events – you can create specific events out of general events

Parallel Extensions and TasksSystem.Threading.Tasks

With those multi core processors everywhere, support for parallelism is an already implicit requirement for any new application. NET 4.0 framework provides a wealth of easy to use primitives and abstractions to enable developers to quickly write parallel programs, targeting multi core machines.

Dynamic ExtensionsSystem.Dynamic

C# 4.0 introduced dynamic capabilities (duck typing) capabilities. There are a number of scenarios where the dynamic features can really simplify things for you. For example, let us assume a Reflection based scenario where you load a type (from an external assembly or so) to invoke a member, or think about a dynamic fluent wrapper on top of XML or JSON.

Read more >>

In Blend, you have the ability to create a copy of the control template of a control, and edit it (Right Click – Edit Template – > Edit A Copy). If you are interested, you can dump the Control template of any given WPF control pretty easily, from the source code as well.

Here is a simple extension method to dump the control template of a WPF control.

 public static class ControlTemplateExtension 
    {
         public static string DumpControlTemplate(this Control ctrl)
        {
            XmlWriterSettings settings = new XmlWriterSettings()
            {
                Indent = true,
                NewLineOnAttributes = true
            };

            StringBuilder strbuild = new StringBuilder();
            XmlWriter xmlwrite = XmlWriter.Create(strbuild, settings);
            XamlWriter.Save(ctrl.Template, xmlwrite);
            return strbuild.ToString();
        }
	}
And now you can go ahead and dump your control templates, like this.

   //use your control name instead of mybutton
   var strXaml = this.myButton.DumpControlTemplate();
   //Do something with your control template
   Debug.WriteLine(strXaml);
Shout it
Read more >>

[+] Download Related Source code

I love to see private thingsFrankly, intrusion in to the private space of others is not so great. Mostly, you’ll get a kick in your ass, but at times, if you are lucky and if you are really smart, you’ll end up finding something really cool (Bond, James Bond).

For me, at times, when doing some hacks/exploration of compiled or third party assemblies, I end up wanting to initialize a private class or a class with a private or internal constructor. Or, at times, when dealing with pre-compiled legacy libraries that I can’t change - I want to write a couple of tests against a private method to understand how it works.  I remember going through the source code of TFS power toys or so some time back - and I found that those guys are bringing up a lot of goodness by unearthing some private classes in the TFS library.

Still, I should warn you.

Warning (assume that this is in red): Private types, internals and private members are so because of some reason, and often you don’t want to mess with them directly. And if you do, chances are that you’ll break later, because there is no guarantee that the guys who created those assemblies will keep the private/internal implementations as such.

If you still don’t mind breaking the rules so that you can un earth some hidden potential against all the danger warnings - here is a quick wrapper class that’ll make the job easy using C# 4.0 dynamic features and reflection.  And more than that, this is a good learning point to see how you can use reflection to initialize private types, invoke private/internal constructors, get/set private properties, invoke private methods etc.

1 – What we are talking about

To explain further what we’ll achieve, consider this simple example.

 
class Program
    {
        static void Main(string[] args)
        {
            //Note that the type of 'wrapper' is dynamic
            dynamic wrapper =  new AccessPrivateWrapper(new ClassWithPrivateMembers()) ;

            //Let us access the private members
            wrapper.somePrivateField = "Field Val";
            wrapper.SomePrivateProperty = "Property Val";
            wrapper.DumpValues();

            Console.ReadLine();
        }

        class ClassWithPrivateMembers
        {
            private string somePrivateField;
            private string SomePrivateProperty { get; set; }

            private void DumpValues()
            {
                Console.WriteLine("Look ma, I'm accessing private members. Prop = "
                    + SomePrivateProperty + ", Fld=" + somePrivateField);
            }

        }
    }

And if you run that, you’ll find that the dynamic wrapper is correctly setting the the private field and property values, and then  invoking a private method in the class (DumpValues method), to print the result.

image

No, we are not yet happy. What about accessing private members in private classes in other assemblies? All right, you can use the FromType method of AccessPrivateWrapper to initialize a private/internal class in a different assembly - and you can initilize the class, even if it's constructor is internal or private. Assume that you have a class named 'ClassWithPrivateConstructor' in an assembly, and it is having a private constructor. And you want to create an instance of that, and to invoke some private members inside. This is what you can do.
            //Note that the wrapper is dynamic
            dynamic wrapper = AccessPrivateWrapper.FromType
                (typeof(SomeKnownClass).Assembly,"ClassWithPrivateConstructor");

            //Access the private members
            wrapper.PrivateMethodInPrivateClass();

2 – What the heck is AccessPrivateWrapper

If you are wondering what exactly is AccessPrivateWrapper – it is a simple class we inherited from the System.Dynamic.DynamicObject class.

But before that If the keyword ‘dynamic’s not not familiar to you, I really suggest you to read this article I wrote earlier - C# 4.0 dynamic keyword – Under the hood

Coming back to DynamicObject - In dynamic languages like Ruby, there is an interesting feature called method_missing. Method missing is where your method request will end if the method you called cannot be found.

In .NET 4.0, now you can bring in the same feature, by inheriting your object from the DynamicObject class. What this means is, you'll get notified when a method/property is invoked/accessed on your object. The DynamicObject class has a few cool methods for you to override. For now, we are only interested in these members:

  • TryInvokeMember - Provides the implementation of calling a member.
  • TrySetMember - Provides the implementation of setting a member.
  • TryGetMember - Provides the implementation of getting a member.

So, we are inheriting our AccessPrivateWrapper from the DynamicObject class, and overriding these methods to access private and public methods, properties and fields via reflection (I hope you know the fact that via reflection, you can invoke, set and get the values of even private and internal members).

Have a look at the implementation of AccessPrivateWrapper

/// <summary>
    /// A 10 minute wrapper to access private members, havn't tested in detail.
    /// Use under your own risk - amazedsaint@gmail.com
    /// </summary>
    public class AccessPrivateWrapper : DynamicObject
    {

        /// <summary>
        /// The object we are going to wrap
        /// </summary>
        object _wrapped;
        
        /// <summary>
        /// Specify the flags for accessing members
        /// </summary>
        static BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance 
            | BindingFlags.Static | BindingFlags.Public;

        /// <summary>
        /// Create a simple private wrapper
        /// </summary>
        public AccessPrivateWrapper(object o)
        {
            _wrapped = o;
        }

        /// <summary>
        /// Create an instance via the constructor matching the args 
        /// </summary>
        public static dynamic FromType(Assembly asm,string type,params object[] args)
        {

            var allt = asm.GetTypes();
            var t=allt.First(item=>item.Name==type);


            var types=from a in args
                      select a.GetType();

            //Gets the constructor matching the specified set of args
            var ctor = t.GetConstructor(flags, null, types.ToArray(), null);

            if (ctor != null)
            {
                var instance = ctor.Invoke(args);
                return new AccessPrivateWrapper(instance);
            }

            return null;
        }

        /// <summary>
        /// Try invoking a method
        /// </summary>
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            var types=from a in args
                      select a.GetType();

            var method = _wrapped.GetType().GetMethod
                (binder.Name,flags, null, types.ToArray(), null);

            if (method == null)
                return base.TryInvokeMember(binder, args, out result);
            else
            {
                result=method.Invoke(_wrapped, args);
                return true;
            }
        }

        /// <summary>
        /// Tries to get a property or field with the given name
        /// </summary>
        public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result)
        {
            //Try getting a property of that name
            var prop = _wrapped.GetType().GetProperty(binder.Name,flags);

            if (prop == null)
            {
                //Try getting a field of that name
                var fld = _wrapped.GetType().GetField(binder.Name, flags);
                if (fld != null)
                {
                    result = fld.GetValue(_wrapped);
                    return true;
                }
                else
                    return base.TryGetMember(binder, out result);
            }
            else
            {
                result = prop.GetValue(_wrapped, null);
                return true;
            }
        }

        /// <summary>
        /// Tries to set a property or field with the given name
        /// </summary>
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            var prop = _wrapped.GetType().GetProperty(binder.Name, flags);
            if (prop == null)
            {
                var fld = _wrapped.GetType().GetField(binder.Name, flags);
                if (fld != null)
                {
                    fld.SetValue(_wrapped,value);
                    return true;
                }
                else
                    return base.TrySetMember(binder, value);
            }
            else
            {
                prop.SetValue(_wrapped, value, null);
                return true;
            }
        }

    }

That looks simple, isn’t it? To detail that a bit, when ever user sets or gets a property or field on our dynamic object, the TrySetMember or TryGetMember will get called - and from there onwards, we use reflection to do the job of setting or getting the property or field value, regardless whether it is private or public. If a property of the given name doesn’t exist we’ll try to find a field of the given name to do the get or set operation.

Similarly, TryInvokeMethod will get fired when the user tries to invoke a method via our dynamic wrapper. We fetch the method matching the type of arguments, to obtain the correct overload, and then do the job via reflection. Make sure you download the code from the above link, and debug through a bit.

Also, pay some special attention to the FromType method that we used earlier. Basically, it’ll find the type to create an instance of, and then will find the constructor to invoke, based on the given arguments.

More Thoughts

Now, what about Unit testing your private members? Ever wanted to do that? That is not a common scenario, but at times, as I mentioned earlier, you might be dealing with a legacy system and you want to write a couple of tests against some of the private methods. Oh yes, you can use the AccessPrivateWrapper to do that.

Note that the above implementation don’t work with libraries that are obfuscated, because we are relying on reflection.

Also, the above implementation won’t access inherited private or internal members. That is pretty simple to implement, but that is an exercise for you ;)

Conclusion

A related tip: You can use InternalsVisibleTo attribute to grant access to the internal members of the target assembly to your caller assembly, if you’ve access to both the assemblies. This is useful, especially when you do unit testing.

Also, check out my other C# 4.0 dynamic tricks

 

Happy Coding!!

Shout it
Read more >>

Related Downloads

What?

Recently a friend asked me to help him create an ‘installer’ to pack and distribute the Silverlight game he recently developed. He wanted to distribute his game via software download websites (like download.cnet.com), and via medias like CD/DVD.

In fact, that is pretty easy (technically) - and this post is about creating and deploying Silverlight Runtime + Your Silverlight application (Xap file) using your very own custom, standalone, offline installer with out getting a browser installed - instead of the user installing your Silverlight application Out Of Browser via the web browser.

Alright. In this post, we’ll see how to build a standalone installer for Silverlight Nerd Dinner Client that I built some time earlier (It is a Silverlight client for Scott’s Nerddinner.com to enable nerds to ‘eat in packs’). The installer will start with a Splash screen as well ;). 

image

About License related issues, see the Appendix towards the end of this post. Also, the scenario I’m discussing is limited to creating installers for Windows machines alone :).

Why?

I can already hear you thinking, “why this is required”? Think about this - You created a Nice game or a Cool gadget in Silverlight. Now you want to create a standalone Installer - so that you can push the same to your potential users via various means. Like, users may download your installer via CNET like software websites - or you may distribute your installer via CD/DVD media etc. In this way, you can push your Silverlight apps to the masses- instead of waiting for them to come to your website and discover it – You got it, that is what we are talking about :).

So, in short, I think Silverlight can be used a platform of choice for building light weight desktop applications, mainly applications like utility tools, light weight games etc.

I feel there are a good number of use cases where you want to do this.

  • You can write and deploy tiny apps and gadgets - with out worrying about the presence of/version of the .NET runtime in user’s machine.
  • You can maintain the same code base for your web and desktop versions if the scenario suits.
  • You can contribute towards increasing the number of boxes where Silverlight exists :). More people with Silverlight = a brighter web ;)

And yes, if you are doubtful about what you can really do from a Silverlight application that is running in an elevated trust, out of browser mode, check out this epic post from Justin Angel where he demonstrates how to do all whacky things with Silverlight + COM, including accessing Win 7 APIs, Accessing Scanners and printers, Adding your OOB application to windows startup etc. He rocks.

How?

So, let us see this in detail - how to create a stand alone installer to install Silverlight Runtime + Your Silverlight Application (i.e, the Xap file). These steps detail how I created my installer for Silverlight Nerd Dinner client.

1 – Preparing the required files

For this example, I’m going to use Nullsoft NSIS Installer to roll down the custom installer. NSIS is a simple windows installer from the WinAmp guys, and you can find ton of information here on that. You can write a custom NSIS script, and make a standalone installer executable out of that.

If you download the example package, you’ll find

  • The NSIS script to create the installer from.
  • The Silverlight runtime installer (Silverlight.exe) – You should ensure you have the latest from here.
  • Copy of your Silverlight Xap (that you are going to install in the user’s machine).
  • A license.txt file and splash.bmp file to show during the time of installation.

Download and Extract the Required Files zip - and have a look at the files I have. I’ve a Nerddinner.nsi script (we’ll soon see what is inside that), the Silverlight.exe runtime installer, SilverlightNerdDinner.xap, a license file and a Splash screen for the installer.

 

image 

2 – What the installer should do

Basically, we need our installer to

  • Copy Silverlight.exe to the user’s machine and execute that in Silent mode to install the Silverlight runtime.
  • Use Sllanucher.exe to install our Xap in out of the browser mode (Sllauncher.exe will be installed by the above Silverlight runtime installer) – Tim already has a nice post on using sllauncher.exe – I’ll also touch that a bit.

The Silverlight deployment guide is a handy read regarding the supported command line arguments for Silverlight.exe and Sllauncher.exe, but here is the summary.

You can install the Silverlight runtime in quiet mode, using the following arguments. 

Silverlight.exe /q /doNotRequireDRMPrompt

The '/q' switch will install the runtime in silent mode. Here is some excerpt from the Silverlight deployment manual version 4.0

  • /q = quiet install or upgrade. This installs or upgrades Silverlight without seeing the GUI. When Silverlight is installed quietly, by default privacy related features such as DRM protected media playback and the Silverlight auto-update feature will be configured to prompt the user for permission on 1st use of the respective features. The Silverlight auto-update feature requires administrative rights so non-admin users will not be prompted.
  • /doNotRequireDRMPrompt = turns off the 1st use prompt allowing content protected by Digital Rights Management (DRM) to play without requiring any end-user intervention. When Silverlight is installed quietly, DRM Playback is set to prompt on 1st use by default.
  • /ignorewarnings = non-fatal warnings will not be reflected in the quiet installer return code but will instead return zero indicating success.
  • /noupdate = disables the Silverlight internal auto-updater.
  • /qu = quiet uninstall. This uninstalls Silverlight without seeing the GUI.

The Silverlight runtime installer will install sllauncher.exe to the {PROGRAMFILES}\Microsoft Silverlight\sllauncher.exe path. So, after installing Silverlight runtime, we may use sllauncher.exe to ‘install’ our xap in Out of Browser mode, and to create the required short cuts

sllauncher.exe 
           /install:"{LocalPathToXapFile}\Yourfile.xap" 
           /origin:"{urltoxapfile}/Yourfile.xap" 
           /shortcut:desktop+startmenu

You can see that Sllauncher.exe will accept the local path to the xap file, the url to the xap file and the shortcut options. Here is some excerpt from the Silverlight deployment manual about using sllauncher.exe to install XAP.

Installation

  • /install:"xapFile" – where xapFile is the file name/file path to the .xap file., E.g. /install:"c:\temp\sample.xap"
  • /origin:"xapURI" – where xapURI is the URI where the .xap file would've come from if not installed at the commandline
    • e.g. /origin:"http://example.com/sample.xap" .  This URI will be used as the site of origin for security purposes. For example, for sandboxed applications, Silverlight networking requires a policy file check when making network requests to domains other than the site of origin.  The origin also serves as a unique ID for the application.  The xapURI must be an absolute URI not a relative URI, and must start with http:, https:, or file:.
  • /overwrite -- (optional) Overwrites any previously installed .xap with that xapURI.

Un installation

  • /uninstall  – Uninstalls the application specified in /origin. This is the same /origin value that was used to install the app originally.
  • /origin:"xapURI" – same as /origin for the install case

3 – The NSIS Script

So, now let us write a quick NSIS script to create an installer that performs these operations. Our script will look like this

Name "Nerd Dinner Desktop Installer"
OutFile "NerdDinnerDesktopInstaller.exe"
InstallDir "$PROGRAMFILES\NerdDinnerDesktop"

XPStyle on

Function .onInit
	# the plugins dir is automatically deleted when the installer exits
	InitPluginsDir
	File /oname=$PLUGINSDIR\splash.bmp "splash.bmp"
	splash::show 1000 $PLUGINSDIR\splash
	Pop $0
FunctionEnd

Section
    SetOutPath "$INSTDIR"
    SetOverwrite ifnewer
    File "Silverlight.exe"
    ExecWait "$INSTDIR\Silverlight.exe /q /doNotRequireDRMPrompt"
    File "SilverlightNerdDinner.xap"
    ExecWait '"$PROGRAMFILES\Microsoft Silverlight\sllauncher.exe" /install:"$INSTDIR\SilverlightNerdDinner.xap" /origin:"http://amazedsaint.net/nerddinner/clientbin/silverlightnerddinner2.xap" /shortcut:desktop+startmenu'
SectionEnd

Basically, the installer will

  1. Show a splash screen during initialization of the installer
  2. Copy Silverlight.exe to the target folder, and execute it in quite mode
  3. Copy our xap file to the target folder, and use sllauncher.exe to install the xap

4 – Creating the Installer

Once you have NSIS installed, you can simply right click on an NSIS file to ‘Compile’ it create an installer.

image

You should see the MakeNSISW prompt, with a message that the installer is created. Our final installer (that contains Silverlight.exe runtime + XAP + Splash Screen image) is almost ~7 MB, and now you can distribute this the way you need, provided you have the permission from Microsoft to re-distribute Silverlight runtime.

image

The above installer will install your Silverlight application and will create the desktop and start menu short cuts. Try the installer from here, and you’ll see that it’ll get installed even in a machine with no Silverlight runtime already present.

When you create the installer from your own XAP file, make sure you have enabled Running your Silverlight Application out of browser. Also, always make sure you’ve the latest version of Silverlight runtime installer, Silverlight.exe (Normally what ever you get from this link )

 

Appendix - Licensing Issues

I asked Tim and Scott whether I can redistribute Silverlight runtime as part of my own custom installer. And this is the reply I got. There is a license available, but it depends on the situation. You should send your app details to Tim for the details :) Also, you might want to show the Silverlight license to the end users as part of your installer. I’m not pretty sure about this – the general recommendation is to fled Tim’s inbox.

image

Having said that, I really think MS should encourage developers to re-distribute Silverlight runtime as part of their custom installers, because that can definitely contribute towards increasing the Silverlight runtime penetration.

Shout it
Read more >>

Suggested Red Polo T-Shirt Replacement for @Scottgu

I’m a @scottgu fan, so can’t stop thinking about this after watching Iron Man 2 ;).

image

Happy Coding!! ;)

 

Recent Tech Posts

Shout it
Read more >>

imageWith those multi core processors everywhere, support for parallelism is an already implicit requirement for any new application. This post explores how easily you can implement parallel features in your application, with .NET 4.0.

What is Parallel computing? From Wikipedia,

Parallel computing is a form of computation in which many calculations are carried out simultaneously,[1] operating on the principle that large problems can often be divided into smaller ones, which are then solved concurrently ("in parallel").

Yes, like that photo indicates, parallel systems can do multiple things at the same time.

.NET 4.0 framework provides a wealth of easy to use primitives and abstractions to enable developers to quickly write parallel programs, targeting multi core machines. In this post, we’ll explore Tasks.

The System.Threading.Tasks has all the classes and abstractions you need to develop applications targeting multi core machines.

What is a Task?

A Task in .NET 4.0 is a simple unit of an asynchronous operation. From .NET 4.0 onwards, it is recommended that you should use Tasks instead of creating your own Thread pool work items. Also, it is recommended that you should avoid creating threads, if you don’t need direct control on a thread’s life time.

Using Tasks

You can simply start a task as shown in the below example.

Assume that we want to do some parallel operations, on a range of numbers. For this example, let us keep things simple – So our ProcessNumbers method is not doing anything more than printing the given range of numbers to a console, but I hope you’ll encounter a lot more useful parallel scenarios when you attack a real problem. We are using the Task.Factory.StartNew method to create a task and start it. The first parameter of StartNew method is the action delegate to execute.

You can start a C# Console application in Visual Studio 2010, to compile and run this code instantly.

using System;
using System.Threading.Tasks;

namespace TasksDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create and start first task
            var t1=Task.Factory.StartNew(() => ProcessNumbers(10, 20));
            //Create and start second task
            var t2=Task.Factory.StartNew(() => ProcessNumbers(20, 30));
            //Create and start third task
            var t3=Task.Factory.StartNew(() => ProcessNumbers(30, 40));
            Console.ReadLine();
        }
        
        //Some complex processing on the range (we are just printing to console, do something better)
        static void ProcessNumbers(int start, int stop)
        {
            for (int i = start; i < stop; i++)
                Console.Write(" " + i);
        }
    }
}

And if you run the above program a couple of times and examine the output, you’ll figure it out that the tasks are getting executed asynchronously, in parallel. See the output screen shot, you’ll figure out that our third task (t3) has started printing the results before our second task (t2) has completed. The output may vary in your machine, and with each run.

image

Waiting For Tasks To Finish using Wait()

You can wait for a task to complete, by calling the Wait method of a task. For example, in our above example, if you want to ensure t3 will start only after t2 and t1 are completed, you should modify the code inside our Main(..) method to

           
           //Create and start first task
            var t1=Task.Factory.StartNew(() => ProcessNumbers(10, 20));
            //Create and start second task
            var t2=Task.Factory.StartNew(() => ProcessNumbers(20, 30));

            //Let us wait till t1 and t2 are completed before starting t3
            t1.Wait();
            t2.Wait();

            //Create and start third task
            var t3=Task.Factory.StartNew(() => ProcessNumbers(30, 40));
            Console.ReadLine();

Can you guess what we are doing here? This will ensure that Task t3 will be started only after t1 and t2 are completed. So, if you examine the output, you’ll find that the numbers 30-40 will be printed only after the first two tasks are finished. How ever, you may still see the output of tasks t1 and t2 are intermingled at times, because they are executing in parallel. Here is my output, (t1 – yellow, t2 – red, t3 – green), your output may vary. How ever, with the above code, you have the assurance that task t3 will start only after t1 and t2 are completed, in any machine.

First run.

image

Second run

image

Yes, as expected, in both cases you found that Task 3 is executing only after T1 and T2 are finished.

Continuing Tasks

You can request a task to continue with some other operations, once it is done with the current operation. For example, what if you want to notify the user after each task is completed?. Modify the code in our Main(..) method to the following. Please note that in this case, we are no longer waiting for t1 and t2 to complete before starting t3. All t1, t2 and t3 will start in parallel.

            //Create and start first task 
            var t1=Task.Factory.StartNew(() => ProcessNumbers(10, 20)); 
            t1.ContinueWith((t) => { Console.Write(" (Finished T1) "); }); 

            //Create and start second task 
            var t2=Task.Factory.StartNew(() => ProcessNumbers(20, 30)); 
            t2.ContinueWith((t) => { Console.Write(" (Finished T2) "); }); 

            //Create and start third task 
            var t3=Task.Factory.StartNew(() => ProcessNumbers(30, 40)); 
            t3.ContinueWith((t) => { Console.Write(" (Finished T3) "); }); 

            Console.ReadLine();

What will happen? If you run the program, you'll find that the message is printed when a task is finished completely, like this (Your output may vary based on the task completion). At this time, task T2 finished first, then T3 and then T1.

image

Let me run this again. This time, I found that task T1 finished first, then T2 and then T3.

image 

Continuing Tasks based on States of Other Tasks

When you do real life programming, you’ll certainly end up in conditions like “Ok, let us start task ‘X’ when task ‘Y’ and task ‘Z’ are completed”, or “Well, we need to start task ‘P’ when task ‘Q’ or task ‘R’ is completed”.

TaskFactory has a couple of interesting methods that’ll help you in such occasions. Let us go back to our old example. Assume that you want to print 30-40 (i.e, our task 3) only after task 1 and task 2 are completed. Of course, one way is to wait till T1 and T2 is completed (See the example under Waiting For Tasks To Finish using Wait), but here is a better way. Use the ContinueWhenAll method in the TaskFactory, like this.

      //Create and start first task
      var t1=Task.Factory.StartNew(() => ProcessNumbers(10, 20));

      //Create and start second task
      var t2=Task.Factory.StartNew(() => ProcessNumbers(20, 30));

      //Start priting 30-40, once t1 AND t2 are finished
      var t3=Task.Factory.ContinueWhenAll(new Task[] { t1, t2 }, 
      (t) => ProcessNumbers(30, 40));
      Console.Read();

The first parameter of ContinueWhenAll(..)  method is an array of tasks, and the second parameter is the action delegate to execute when all tasks in the input array is completed.

Similarly, another interesting method is ContinueWhenAny(..). The following example shows how to start a task, when any of the given set of tasks are finished.

          //Create and start first task
            var t1=Task.Factory.StartNew(() => ProcessNumbers(10, 20));

            //Create and start second task
            var t2=Task.Factory.StartNew(() => ProcessNumbers(20, 30));

            //Start printing 30-40 when t1 OR t2 is finished
            var t3=Task.Factory.ContinueWhenAny(new Task[] { t1, t2 }, 
                (t) => ProcessNumbers(30, 40));

            Console.Read();

You can achieve almost any parallel sequence scenario by nesting ContinueWhenAll(..) and ContinueWhenAny(..)

Returning value from a task

You may use the StartNew<> method to start a task that’ll compute and return a value. For example, assume that you have a function that’ll return the sum of a range, and you want to execute the summation of various ranges in parallel. Here is a quick program that’ll do the same. Have a look at this example.

using System;
using System.Threading.Tasks;

namespace TasksDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create and start first task
            var t1 = Task.Factory.StartNew<int>(() => SumRange(10, 20));
            //Create and start second task
            var t2 = Task.Factory.StartNew<int>(() => SumRange(20, 30));
			
	        //Wait till both the tasks finish, sum the results
            var allsums = t1.Result + t2.Result;
            Console.WriteLine(allsums);
            Console.Read();
        }
        
        //Sum the numbers
        static int SumRange(int start, int stop)
        {
            int sum = 0;
            for (int i = start; i < stop; i++)
                sum += i;
            return sum;
        }
    }
}

Needless to explain, in the above example, we are finding the sum of all values in two value ranges, and then sum the results together. The interesting point to note here is, when you access the computed Result of a task, the task will automatically wait there to complete, so that the computed result can be returned correctly.

I’ll soon write about Parallel Loops and PLINQ, so keep in touch and subscribe to this blog if you are interested. Or, you may follow me in twitter. 

Have you read this post about 6 Cool features in Visual Studio 2010 to improve your productivity?

Shout it
Read more >>

top