Managed World

An Odyssey Through The Land Of Geekdom

  Home  |   Contact  |   Syndication    |   Login
  464 Posts | 0 Stories | 205 Comments | 1338 Trackbacks

News

Add to Technorati Favorites

Archives

Post Categories

Blog Roll

Sunday, January 04, 2009 #

Here's a sneak peek at a project/library I'm currently working on:

include Microsoft::Xna::Framework
include Microsoft::Xna::Framework::Graphics
include RubyXna

class FluxxGame < RubyXnaGame
    def initialize
        self.background_color = Color.black
    end

    def load(loader)
        @font = loader.load_font("Title")
    end

    def render(renderer)
        renderer.draw_text(@font, "Fluxx, v0.1", Vector2.zero, Color.white)
    end
end

The combination of IronRuby and XNA Game Studio is proving to be pretty darn fun!


Wednesday, December 24, 2008 #

Happy Holidays, everybody! First of all, thanks to everybody who helped get the word out on the launch of this new show on Channel 9 by blogging, tweeting, or spreading the word using other ways. There is no doubt in our minds that the launch of this new show wouldn’t have been nearly as successful without all of you!

In this second episode of 10-4, we’ll take a very high-level look at Visual Studio 2010. We’ll discuss what types of features you can expect to see in Visual Studio 2010 and .NET Framework 4.0 depending on what type of developer you are. And lastly we’ll go ahead and dive into a revised area of Visual Studio: the Start Page. The Start Page in Visual Studio 2010 has been revised to be XAML-based and allows full customization.

In future episodes we’ll dive more deeply into the technical underpinnings of Visual Studio 2010 and the .NET Framework 4.0, but for this second episode we want to make sure everybody gains an understanding of what different areas are being focused in Visual Studio 2010. While an overview is given, there is only so much time and so many features we can talk about. So if you don't see something mentioned, don't worry as we have a lot more information to dive into in the coming weeks and months.

For more 10-4 episodes, be sure to visit:
http://channel9.msdn.com/Shows/10-4/

Over and out!


Sunday, December 14, 2008 #

This question/conversation has come up quite often when chatting with friends and other developers. With the introduction of the "var" keyword in C# now, when should it be used (and, perhaps more importantly, when should it not be used). Here is a quick summary on my thoughts...

My personal feeling is that it's a problem if I have to rely on Intellisense in order to be able to tell what type a variable is when it is declared. It's important to keep the future audience in mind while you are writing code (this could be future developers needing to maintain your code, or even yourself years down the road). After all, writing code is the easy part. Reading it (and hence, reverse engineering it to a degree) is the hard part.

So, when you write code that requires another developer to use Intellisense (or go poking around other pieces of code that may be contextual irrelevant) to understand a piece of code, I would contend that you are not writing good code.

This brings us to the var keyword. Good usage? Using it to automatically infer variable types on declaration/instantiation lines of code:

var people = new List<People>();
var lookup = new Dictionary<string, SomeType>();

However, I really don't like when developers use the var keyword on a variable declaration based on the return of a method call. Without Intellisense, how am I supposed to be able to tell what type the variable is?

// This is *bad*, don't do this
var local = SomeMethod(...);

How about loop variables? My personal take (though I could go either way) is to not use the var keyword on loops:

// I prefer this
for (int i = 0; i < 10; i++)
{
...
}

// over this
for (var i = 0; i < 10; i++)
{
...
}

In general, I think it is important not to be a lazy coder and do something just because it makes it easier on you at the time. As a developer, you need to think about those that will come after you and maintain your code. Don't make it any harder on them than it needs to be. Their jobs are already hard enough.

What are your thoughts? Where do you use the var keyword? Where do you NOT use the var keyword?


Tuesday, October 28, 2008 #

Great news everybody! I just got word that Day 2 of the PDC (that's Tuesday), at 12:45pm, Steven Sinofsky will be giving a 30 minute Open Space session on "Windows 7 Keynote Discussion."

Yes, that's correct. The Senior Vice President of Windows and Windows Live will be in Open Space at 12:45pm to discuss with you, our customers, what you think about the announcements made in Tuesday morning's keynote on Windows 7.

So if you want to get the ear of the man in charge of Windows (who only answers to Steve Ballmer himself), make sure to drop by Open Space Tuesday afternoon at 12:45pm to partake in what is sure to be a great discussion!


Thursday, October 23, 2008 #

I'm VERY excited to finally talk about this publicly. A while ago, I was able to start playing around with a programming language called SmallBasic being developed internally at Microsoft by Vijaye Raji. And now, it's finally been announced as part of our new Dev Labs effort.

So what is SmallBasic? From the website:

"Small Basic is a project that's aimed at bringing "fun" back to programming. By providing a small and easy to learn programming language in a friendly and inviting development environment, Small Basic makes programming a breeze. Ideal for kids and adults alike, Small Basic helps beginners take the first step into the wonderful world of programming."

Why develop SmallBasic? Well, I can tell you the reason that I'm excited about it. I personally feel that in the absence of QBASIC, GWBASIC, etc., there is no longer a programming language that is easy for non-programmers to get hooked with. All our modern .NET languages currently are more "professional" languages. But what is out there for 6-10 year olds (for example) to play around with easily in order to "get the bug" of programming. Nothing from Microsoft, if you ask me.

 

This is why I'm so ecstatic that SmallBasic is finally available publically (keep in mind, it's not an official product, simply DevLabs bits that you can play around with). So, even if you are a professional programmer, feel free to go over, download it, and play around for a bit.

One of my favorite things? For one, the editor. It's a pretty clever take on Intellisense and the editor is a great example of a "friendly" IDE.

Enjoy!


Thursday, October 16, 2008 #

I've announced previously about the inclusion of Open Space at PDC 2008 this year. I'm here to let you know some of the details of how Open Space will work at PDC and how anybody at PDC can participate.

Believe it or not, Open Space is going to be open anytime there are sessions going on at PDC. The first thing you need to know about is how you can participate in the conversation and perhaps even suggest a conversation that you wish to moderate (or just wish to discuss).

A description of the process straight from Wikipedia:

At the beginning of an Open Space the participants sit in a circle, or in concentric circles for large groups (300 to 2000 people).

The facilitator will greet the people and briefly re-state the theme of their gathering, without giving a lengthy speech. Then someone will invite all participants to identify any issue or opportunity related to the theme. Participants willing to raise a topic will come to the centre of the circle and announce it to the group.

 

Someone writes the topics on sheets of papers which get posted on a wall, creating an agenda. No participant must suggest issues, but anyone may do so. However, if someone posts a topic, the system expects that the person has a real passion for the issue and can lead the discussion on it. No limit exists on the number of issues that the meeting can post.

 

When someone determines that the posting of all issues has finished, the meeting sets times and places for the individual sessions; and participants sign up for those individual sessions. Sessions typically last for 1.5 hours. The opening session lasts about an hour, even with a very large group.

 

After the opening session, the individual groups go to work. The attendees organize each session; people may freely decide which session they want to attend, and may switch to another one at any time. Online networking can occur both before and following the actual face-to-face meetings so discussions can continue seamlessly.

So, how is this going to work while PDC sessions are going on? Here's what the Open Space schedule looks like:

  • Monday
    • 11:00am-12:45pm - Opening Circle - Agenda Creation
    • 12:45pm-6:30pm - Open Space sessions (aligned with conference session schedule)
  • Tuesday
    • 12:30pm-1:45pm - Opening Circle - Agenda Creation
    • 1:45pm-6:00pm - Open Space sessions (aligned with conference session schedule)
  • Wednesday
    • 10:00am-10:30am - Opening Circle - Agenda Creation
    • 10:30am-5:00pm - Open Space sessions (aligned with conference session schedule)
  • Thursday
    • 9:30am-10:15am - Opening Circle - Agenda Creation
    • 10:15am-1:45pm - Open Space sessions (aligned with conference session schedule)
    • 1:45pm-3:00pm - Closing Circle

So if you are going to be in attendance at PDC 2008, feel free to drop by an participate in Open Space. And if you participate during the week, we highly encourage you to attend the Closing Circle to help close the (Open Space) loop!

We look forward to seeing you there!


Thursday, September 18, 2008 #

I've talked in the past about the importance of parallel computing for all us developers. It's a trend in computer software and hardware architecture that is not a fad. Currently, in the US, it is nearly impossible to buy a new computer that has only a single core. We're even starting to see some of the first quad-core laptops hit the market.

It's becoming very important for developers to start dealing with parallel code. There's one problem: multithreaded development is hard. And in the class of Threading 101, Race Conditions is one of the first chapters you have to deal with.

So what is a Race Condition? According to Wikipedia, the source for all information on the Internet (emphasis mine):

"A race condition, or race hazard, is a flaw in a system or process whereby the output and/or result of the process is unexpectedly and critically dependent on the sequence or timing of other events. The term originates with the idea of two signals racing each other to influence the output first."

That's nice and all, but what does this mean to us developers? Let's look at a simple example. I have a Logger where I want to keep track of the number of messages that are logged.

   1: class Logger
   2: {
   3:     public static int TotalMessages = 0;
   4:  
   5:     public void Log(string message)
   6:     {
   7:         // Do something with message
   8:         TotalMessages++;
   9:     }
  10: }

Now let's call this method a bunch of times from four different threads and capture the total number of times Log message was called:

   1: int messagesPerTask = 200000;
   2: int unitsOfWork = 4;
   3:  
   4: var logger = new Logger();
   5: Parallel.For(0, unitsOfWork, (taskNumber) =>
   6: {
   7:     for (int i = 0; i < messagesPerTask; i++)
   8:     {
   9:         logger.Log("Message " + i.ToString());
  10:     }
  11: });
  12:  
  13: Console.WriteLine("{0} Expected", messagesPerTask * unitsOfWork);
  14: Console.WriteLine("{0} Actual", Logger.TotalMessages);

What do you expect the output to be? The obvious answer is "well, we are adding 200000 messages on four different threads, so it's obviously 800000". Unfortunately, the obvious answer also happens to be the wrong answer. What's the right answer? It depends, and it can change every single time you run the application. For example, this were the results from the first time I ran the code:

800000 Expected
680354 Actual

Wait... how is this possible? Did we lose updates? Did I not call the method enough times? This surely must be a horrendous bug in the .NET Framework! Damn Bill and his blasted company. Trust me, it's not a bug. There's a good explanation of this behavior.

If you haven't written a lot of multithreaded code yet, the problem with the above code may not be obvious. Truth be told, there really isn't a problem with the code... IF you are only running the code on a single thread ever. But the likelihood of running on a single thread is becoming smaller and smaller. And as you can see, when we are running this in a multithreaded environment, there is most definitely a problem with the code.

A lot of .NET developers look at "TotalMessages++" and interpret it as one line of code, one execution, one instruction, etc. But there's the rub, it isn't. The code "TotalMessages++" is actually four instructions when compiled down to IL.

   1: L_0001: ldsfld int32 CSharpSandbox.Logger::TotalMessages
   2: L_0006: ldc.i4.1 
   3: L_0007: add 
   4: L_0008: stsfld int32 CSharpSandbox.Logger::TotalMessages

These four lines essentially say the following:

  1. Get the current value of TotalMessages
  2. Get the value 1
  3. Add the two numbers together
  4. Save the result back into TotalMessages

Now let's imagine two threads executing the four steps above at the same time. Since threads won't be in perfect lock-step, they may be off by two steps (assuming the value of TotalMessages is currently 2):

[Thread 1] 1. Get the current value of TotalMessages (gets 2)
[Thread 1] 2. Get the value 1

[Thread 2] 1. Get the current value of TotalMessages (gets 2)
[Thread 2] 2. Get the value 1

[Thread 1] 3. Add the two numbers together (2 + 1)
[Thread 1] 4. Save the result back into TotalMessages (saves 3)

[Thread 2] 3. Add the two numbers together (2 + 1)
[Thread 2] 4. Save the result back into TotalMessages (saves 3)

So we've executed that code twice and at the end of the execution, TotalMessages has only increased by one. This is exactly what a race condition is. It's that simple. It's not as advanced as a concept as one might think.

This is why developers need to understand what race conditions are. A snippet of code that looks completely innocuous can cause some big problems when run in a multithreaded development. While future technologies will make writing parallel code easier, it won't prevent these types of problems from occurring. You still need to be aware of some of the common Threading 101 concerns/topics that exist today.


Wednesday, July 30, 2008 #

If you want to see real F# programming showing off the power of function composition, I found some great blog posts earlier tonight. They are actually by Dustin Campbell on his blog: http://diditwith.net/CategoryView,category,Project%2BEuler.aspx.

 

I think these posts are some of the best F# posts I have seen out there so far. I love them because they show off the real beauty and power of F#, and don't do the whole “here’s how F# can behave like other languages” treatment that I’ve seen in so many other places.

 

Those posts (and any other F# posts on Dustin’s blog) are a MUST READ if you are at all interested in F# or functional programming.


Friday, July 04, 2008 #

How would you like to use the following way to configure dependencies in MEF? A fluent interface with POCO support (no attributes necessary)? Yup.

            var resolver = new FluentResolver();
            resolver.Register<HelloWorld>().
                And<HelloGreeting>().As<IGreeting>().
                And<ConsoleOutputter>().As<IOutputter>();

            var domain = new CompositionContainer(resolver);

            // HelloWorld has dependencies on IGreeting and IOutputter
            var helloWorld = domain.Resolve<HelloWorld>();
            helloWorld.SaySomething();

Lately I've been digging more and more into the first CTP of the Managed Extensibility Framework (MEF) coming out of Krzysztof Cwalina's team here at Microsoft. By default, a developer needs to sprinkle Export and Import attributes in their classes at the point they are needing something to be injected, or on classes that need to be exported in order to be injected into other classes. However, if you don't like this behavior, MEF provides several extension points you can use to provide a different interface into MEF.

In my "ideal" Dependency Injection interface for MEF, there are several requirements that I would like:

  • No Export/Import attributes necessary; hence, support for POCOs (Plain Ol' CLR Objects)
  • Registration of types with container, not registration of object instances (where I would have to create the object myself before adding it's type to the container).
  • Simply ask container to resolve a type into an instance for me. Other than the container and resolver, none of my "domain objects" should be "new"-ed up by me.
  • No need to tell the CompositionContainer to Bind(). It should know about all the types necessary.
  • For "ease of use", I want to configure dependencies via a Fluent Interface.

I'm on a little bit of a Fluent Interface kick right now. I admit it. My name is Jason Olson and I'm a Fluent Interface junkie. If I could type emails via a Fluent Interface in code (rather than Outlook), I probably would. My addiction is just... that... bad.

Before we dig into how we will leverage MEF's extension points, let's just take a quick peek at the classes we are wanting to wire up via the interface shown above:

    class HelloWorld
    {
        public IGreeting Greeting { get; set; }
        public IOutputter Outputter { get; set; } 

        public void SaySomething()
        {
            // Our dependencies above determine where the output
            // is written to, and what the greeting will be.
            Outputter.WriteLine(Greeting.Greet());
        }
    }

    interface IGreeting
    {
        string Greet(); 
    }

    class HelloGreeting : IGreeting
    {
        public string Greet() 
        {
            return "Hello Fluent Interface!";
        }
    }

    interface IOutputter
    {
        void WriteLine(string message); 
    }

    class ConsoleOutputter : IOutputter
    {
        public void WriteLine(string message)
        {
            Console.WriteLine(message);
        }
    }

So how do we enable this new behavior? There are two primary MEF extension points we will use, a custom ComponentBinder and a custom ValueResolver. According to the CTP documentation (emphasis mine):

"The role of the ComponentBinder is to create a collection of primitives associated with its component. There is only one ComponentBinder per component. The CompositionContainer will use the collection of binders during the bind operation to determine how components need to be wired-up."

In this case, "collection of primitives" essentially means the export and imports of the component it is bound to. One of the interesting points to note is that the CompositionContainer uses these ComponentBinders to determine how various components need to be created. So for MEF to determine what the various imports and exports are for wiring up components, it can use our custom ComponentBinder to do so. So while the default ReflectionBinder will generate this information via attribute declarations on the components in question, we can change this behavior if we wish.

The other extension point we will use is a custom ValueResolver. Once again, according to the CTP documentation (emphasis mine):

"A ValueResolver allows the composition container to retrieve components from some sort of repository. The composition container’s bind operation has the single goal of satisfying all imports for all components that were explicitly added to it. During a bind operation, the composition container can query the ValueResolver for exports if it deems it necessary (e.g. no exports currently in the composition container satisfy a specific import, an import is requesting a collection of all available exports, etc.)."

To implement these two extension points, we will need two custom classes: FluentResolver and FluentBinder. Our FluentResolver is what we use to build up a map of our dependencies via the fluent interface shown above. When the FluentResolver is then passed into a CompositionContainer, we will go through our dependency map and crank out a bunch of FluentBinders that MEF can then use when needing to create various objects the user is asking for.

First, our FluentResolver. FluentResolver contains the methods that make up our fluent interface and that will hold the dependency map we are building up. And then we our FluentResolver is hooked up to a CompositionContainer, we will use this "dependency map" in order to build up all the FluentBinder instances that MEF will use to wire up all our dependencies.

    class FluentResolver : ValueResolver, IRegisterChainer
    {
        private Type lastRegisteredType;
        private IDictionary<Type, IList<Type>> exportTypes = new Dictionary<Type, IList<Type>>();
        private IList<Type> registeredTypes = new List<Type>();

        // The following three methods define our fluent interface
        // (Register<T>, And<T>, and As<T>).
        public IRegisterChainer Register<T>() where T : class, new()
        {
            if (!exportTypes.ContainsKey(typeof(T)))
            {
                exportTypes.Add(typeof(T), new List<Type>());
            }

            exportTypes[typeof(T)].Add(typeof(T));
            registeredTypes.Add(typeof(T));

            lastRegisteredType = typeof(T);
            return this;
        }

        public IRegisterChainer As<T>() where T: class
        {
            // Add exported type to last registered type (the call right
            // before .As<T>() in the fluent interface). This is used
            // to register a type as an interface, rather than the
            // concrete type.
            exportTypes[lastRegisteredType].Add(typeof(T));
            return this;
        }

        public IRegisterChainer And<T>() where T : class, new()
        {
            // Just a different way to register so that the fluent
            // interface is easily readable.
            return Register<T>();
        }

        // This is where the "magic" happens. When our container is set (like
        // when we are passed into the constructor of a container), we will
        // create all of our custom binders that MEF will then use to wire-up
        // dependencies.
        protected override void OnContainerSet()
        {
            base.OnContainerSet();

            foreach (var type in registeredTypes)
            {
                // An "Import" (read: injected dependency) is defined as any property whose
                // type is a type that is "exported" from any other registered type
                var imports = (from pi in type.GetProperties()
                               from export in exportTypes
                               where export.Value.Contains(pi.PropertyType)
                               select pi).Distinct();

                // Export all types our specific type has been asked to export and all the 
                // properties from above that are dependencies we need to inject.
                Container.AddBinder(new FluentBinder(type, exportTypes[type], imports.ToList()));
            }
            
            // Since all the dependencies are known from our fluent interface,
            // automatically bind the container so that the user doesn't have to
            // call Bind() themselves.
            Container.Bind();
        }

        public override CompositionResult<IImportInfo> TryResolveToValue(string name, IEnumerable<string> requiredMetadata)
        {
            // Same as TryResolveToValues below, except we just return a
            // single value, rather than a collection of values.
            var result = TryResolveToValues(name, requiredMetadata);

            return new CompositionResult<IImportInfo>(result.Succeeded, 
                result.Issues, 
                result.Value.First());
        }

        public override CompositionResult<ImportInfoCollection> TryResolveToValues(string name, IEnumerable<string> requiredMetadata)
        {
            // Based on all the custom binders we have created, have
            // the container get the various dependent components for us.
            return TryGetContainerLocalImportInfos(name, requiredMetadata);
        }
    }

IRegisterChainer is simply an interface our three fluent methods (Register<T>, And<T>, As<T>) return (and that FluentResolver implements) that allows us to keep on chaining our method calls one after the other, hence enabling our fluent interface.

    interface IRegisterChainer
    {
        // Allows registering another dependency into our resolver
        IRegisterChainer And<T>() where T : class, new();

        // Enables registering a depedency as a specific type (like
        // an interface) on top of the concrete type it directly implements
        IRegisterChainer As<T>() where T : class;
    }

And now on to our FluentBinder:

    class FluentBinder : ComponentBinder
    {
        // An instance of the type we are the binder for
        private object instance;

        // The types we export (could be our concrete type, interfaces, etc.)
        private IList<Type> exports;

        // Our properties that are dependencies needing resolving
        private IList<PropertyInfo> imports;
       

        public FluentBinder(Type type, IList<Type> exports, IList<PropertyInfo> imports) 
        {
            this.exports = exports;
            this.imports = imports;

            // In the future, we could use constructor injection here. For now,
            // just use the default constructor and property injection.
            instance = type.GetConstructor(new Type[] {}).Invoke(new object[] {});
        }


        public override IEnumerable<string> ExportNames
        {
            // Return the name of the Types we are Exporting
            get { return exports.Select(t => t.ToString()); }
        }

        public override CompositionResult Export() 
        {
            // Add our object instance into the container for every type
            // that we are exporting.
            foreach (var type in exports)
            {
                AddValueToContainer(type.ToString(), instance);
            }

            return new CompositionResult(true, new List<CompositionIssue>());
        }

        public override IEnumerable<string> ImportNames
        {
            // Return the name of the Types we need Imported
            get { return imports.Select(pi => pi.PropertyType.ToString()); }
        }

        public override CompositionResult Import(IEnumerable<string> changedValueNames) 
        {
            // Import every property we have that is a dependency
            foreach(var propertyInfo in imports)
            {
                // Inject an instance of the type of our property from the container
                var component = Container.TryGetBoundValue(propertyInfo.PropertyType.ToString(), 
                    propertyInfo.PropertyType);

                propertyInfo.SetValue(instance, component.Value, null);
            }

            return new CompositionResult(true, new List<CompositionIssue>());
        }
    }

This FluentBinder is essentially the heart of the our behavior. We use the the results from our FluentResolver that are passed in to our binder to let MEF know what types we need to import and what types we are exporting from the type FluentBinder is bound to.

The final thing we need to enable our desired API from above is an extension method to CompositionContainer called Resolve<T>() which we just give the type that we would like an instance of. I just happen to think this thin wrapper around TryGetBoundValue<T>() is easier to use and better to read.

    static class CompositionContainerExtensions
    {
        public static T Resolve<T>(this CompositionContainer domain)
        {
            return domain.TryGetBoundValue<T>().Value;
        }
    }

And now we can combine all the pieces together to build our sample application:

    class Program
    {
        static void Main(string[] args)
        {
            // Declare dependencies via a fluent interface.
            // No need for attributes, XML config, or 
            // registration of instances of objects.
            var resolver = new FluentResolver();
            resolver.Register<HelloWorld>().
                And<HelloGreeting>().As<IGreeting>().
                And<ConsoleOutputter>().As<IOutputter>();

            // Pass in our custom resolver and have it help
            // take care of the binding process.
            var domain = new CompositionContainer(resolver);

            // Ask the container for an instance of a type.
            var helloWorld = domain.Resolve<HelloWorld>();
            helloWorld.SaySomething();

            Console.ReadKey(true);
        }
    }

While the fluent interface might be seen as a potential "big departure" from the way MEF works out-of-the-box, you can see that it is very possible (and not too difficult) to change how dependencies are configured with MEF. You might want your configuration in an XML file, in a DSL defined in a map.txt file, in a database (no I don't know why you'd want that :P), etc. And no matter how you want it done, it is possible for you to do so with just a little coding.

Until next time, Happy Coding!

Obviously, this is just a sample prototype and doesn't have several features necessary in DI containers. So, more reason for me to write some more code :). Also, remember this is built on the first CTP of MEF, so the odds are that it will become out-of-date at a later time.


Saturday, June 21, 2008 #

As developers get up to speed with the CCR, they quickly come across the (ab)use of iterators to achieve "concurrency." Okay, "(ab)use" may have been a bit of a low-blow. I call it an abuse as it is a totally unorthodox use of what iterators are usually used for, and I've came across my fair share of developers who find this unorthodox usage highly confusing. Not only is it confusing, but it's not what I would consider true concurrent code.

In a concurrent environment, if I create twenty different tasks that need to be executed, I expect several of those tasks to be executed at the exact same time (depending on the number of processors I have on my system). As a side effect of this concurrent execution of tasks, the order in which those tasks are executed is not guaranteed. If you don't have several tasks executing concurrently, and order of processing is indeed guaranteed, that's about as close you can get to being normal sequential code.

Look at this sample (example 18) from MSDN. If you execute and step through this code, you will find that the method actually executes sequentially. The code posts a number, processes the number, posts another number, processes that number, etc. This is highly sequential. One could argue this is simply not the best sample for CCR iterators. However, after using CCR when developing robots using Robotics Studio, you will find that this "sequential but not" pattern is a very frequent pattern that is used when using CCR iterators.

There's also the impact of having a method that essentially never exits due to the "while (true)" nature of the iterator-based method that is determining what tasks need to execute (leading to a highly coupled, monolithic application). This doesn't mean that the CCR itself isn't useful though. You just need to know how to leverage the framework while avoiding some of these "rough spots".

So let's take a look at an example of how to use CCR to achieve "true" concurrency with the CCR without the use of iterators (for you VB fans, the great part of this approach is that it is entirely possible with VB like I show here).

Dim myPort As New Port(Of Integer)

At the heart of the message-based infrastructure in the CCR is a Port. A Port is where messages are posted to, and pulled from when tasks are actually executed. As seen above, Ports are strongly typed through the use of generics, and so they support posting/pulling of largely any POCO (Plain Ole CLR Object) you wish. In the case of this very simple demo we just use integers, but in a real system this might be self-defined types like StockQuoteRequestMessage, FoodOrderMessage, etc.

    Sub Main()
        Dim taskDispatcher As New Dispatcher(4, "Sample Dispatcher")
        Dim taskQueue As New DispatcherQueue("Sample Tasks", taskDispatcher)

In the CCR, a DispatcherQueue contains a list of tasks to be executed, while a Dispatcher controls the execution of those tasks. Here we force our dispatcher to run four tasks concurrently even if we are on a single processor machine just so we can see the concurrency in action. Then we simply pass our dispatcher to the queue that contains the tasks that will be managed.

        ' Create the task that will handle our work
        Dim workReceiver = Arbiter.Receive(Of Integer)(True, _
                                myPort, _
                                Function(i) ProcessValue(i))

        ' Register the task with the CCR task queue
        Arbiter.Activate(taskQueue, workReceiver)

        ' Post some work to do
        For i = 0 To 9
            myPort.Post(i)
        Next

When we create our workReceiver, we are essentially telling the CCR that we want a persistent task (one that will last across the processing lifetime of many messages, possibly until the application exits), and that when a message comes in on our Port, we will process that message with our function ProcessValue (defined below). Once the receiver is created, we simply hook it up to the task queue, and we're off to the races.

Finally, all we need to do is wait until all values have been processed and exit the application.

        ' Wait until all tasks are finished
        While myPort.ItemCount > 0
            Thread.Sleep(TimeSpan.FromMilliseconds(200))
        End While

        taskQueue.Dispose()
        taskDispatcher.Dispose()

        Console.Write("Press any key to exit...")
        Console.ReadKey(True)
    End Sub

So when a message is posted to our port, CCR will call our function ProcessValue in order to process the message (as specified when we created the task to process messages). In our process function, we are simply going to write to the console at the beginning and at the end as well as sleeping our thread in the middle to simulate some work being done in the function.

    Function ProcessValue(ByVal value As Integer)

        Console.WriteLine("Begin " + value.ToString())
        Thread.Sleep(TimeSpan.FromMilliseconds(200))
        Console.WriteLine("End " + value.ToString())

        Return Nothing
    End Function

When I actually execute this sample, you can see the parallel nature of the execution by viewing the output (your output may differ as it can differ upon every execution thanks to the non-deterministic nature of concurrency):

Begin 0
Begin 1
Begin 3
Begin 2
End 2
Begin 4
End 1
Begin 5
End 0
Begin 6
End 3
Begin 7
End 4
Begin 8
End 5
End 6
Begin 9
End 7
End 8
End 9
Press any key to exit...

 

And that's all we need to do in order to use CCR to process incoming messages in parallel (and in a "true" concurrent fashion). Just as a recap, here's the entire sample in one place:

    Dim myPort As New Port(Of Integer)

    Sub Main()
        Dim taskDispatcher As New Dispatcher(4, "Sample Dispatcher")
        Dim taskQueue As New DispatcherQueue("Sample Tasks", taskDispatcher)

        ' Create the task that will handle our work
        Dim workReceiver = Arbiter.Receive(Of Integer)(True, _
                                myPort, _
                                Function(i) ProcessValue(i))

        ' Register the task with the CCR task queue
        Arbiter.Activate(taskQueue, workReceiver)

        ' Post some work to do
        For i = 0 To 9
            myPort.Post(i)
        Next

        ' Wait until all tasks are finished
        While myPort.ItemCount > 0
            Thread.Sleep(TimeSpan.FromMilliseconds(200))
        End While

        taskQueue.Dispose()
        taskDispatcher.Dispose()

        Console.Write("Press any key to exit...")
        Console.ReadKey(True)
    End Sub

    Function ProcessValue(ByVal value As Integer)

        Console.WriteLine("Begin " + value.ToString())
        Thread.Sleep(TimeSpan.FromMilliseconds(200))
        Console.WriteLine("End " + value.ToString())

        Return Nothing
    End Function

As a "hello world" sample for using the CCR, this is a very simple demo. But it shows that it is very easy to actually achieve concurrent applications with the CCR without having to use CCR iterators. At the same time, avoiding the use of CCR iterators enable us to write a message-oriented application that can be properly modularized by "separating concerns" into independent message processors through the use of Ports.

Of course, an added benefit of taking a "non-iterator" approach when using the CCR is that languages that don't have direct support for iterators (like VB.NET) can also develop CCR-based applications to achieve highly-parallel solutions.