Critical Development

Language design, framework development, UI design, robotics and more.

Archive for July, 2008

Multiple Generic Type Parameters & Limitations on Constraints

Posted by Dan Vanderboom on July 23, 2008

After daily use for years, I keep running into new situations with newer C# language features, even with generics which have been around since .NET 2.0. Just as a quick refresher, in case you’re not familiar with generics or have been stuck on .NET 1.1 for a while, here’s a simple generic method to succinctly determine if some type is decorated with an attribute:

public static bool HasAttribute<T>(this Type Type)
{
    foreach (Attribute attr in Type.GetCustomAttributes(typeof(T), true))
    {
        if (attr.GetType() == typeof(T))
        {
            return true;
        }
    }
    return false;
}

I can call it like this:

bool HasParseAttr = SomeObject.GetType().HasAttribute<ParseAttribute>();

Generic constraints are defined with a “where” clause, so you can ensure that a type that’s passed in implements a specific interface, you can ensure the type is a reference type (class) or a value type (struct), you can ensure that it has a constructor (new), or you can ensure it inherits from some other type.

public static bool HasAttribute<T>(this Type Type)
    where T : Attribute
{
    // ...
}

Here I’m ensuring that T inherits from the Attribute class.

Some of the code I wrote today required different constraints on multiple type parameters. I tried using &&, and commas, but those didn’t work, so a quick Google search gave me the answer—the use of multiple where clauses:

private void RegisterDataBindingMethods<AttributeType, DelegateType>(ref Dictionary<string, DelegateType> Methods)
    where AttributeType : Attribute
    where DelegateType : Delegate
{
    // ...
}

The problem is that “special types”, such as object and Delegate, can’t be used for generic constraints. For object, you can use class or new(), but why not Delegate?  Is this an artificial restriction?

Within the body of this method, I ran into another odd problem:

Delegate del = Delegate.CreateDelegate(typeof(DelegateType), this, mi);
Methods.Add(PropertyName, (DelegateType)del);

This won’t compile, because there’s no way to know if del can be casted to a DelegateType at compile time. However, if I add the constraint where DelegateType : class, then I can do this:

Methods.Add(PropertyName, (del as DelegateType));

This works fine, because it will attempt at runtime to convert it. If it fails, the resulting expression will be null.  Although C# isn’t always very intuitive, there is almost always a way to accomplish what you’re attempting.

I’ve been impressed by the ways in which fundamental design patterns, as well as my general development approach, have changed (sometimes drastically) due to a handful of new language features, and while most of that has been due to the fantastic features added in C# 3.0, I  occasionally run into situations where older features like generics still surprise me.

Advertisements

Posted in Design Patterns, Reflection | Leave a Comment »

Bad SDK Installation Practices

Posted by Dan Vanderboom on July 8, 2008

Some Compact Framework SDKs (SQLCE, Symbol, OpenNETCF), when they install on a development machine, install a deployment “package”, which is a Visual Studio construct that associates one or more assemblies with a CAB file.  When you add a reference to one of those assemblies and deploy to a device, the entire CAB file installs instead of the individual assembly.

In Visual Studio 2005, the definition of these deployment packages consists of an XSL file deeply nested in the Application Data folder (the file name is conman_ds_package.xsl).  Though I couldn’t find any reference to this at all on the Internet when I first played around with this, you can edit this file, and even remove package definitions altogether, which will circumvent this mechanism and deploy only the assemblies you explicitly reference, as you would expect it to behave in the first place.

I’m not recommending this as a general practice, but it sometimes comes in handy: it’s nice to have that level of control over which assemblies are selected and how they get deployed.  My article on the frustrations and oddness with references illustrates some of the problems of “hiding the details” to such an extent that the ultimate behavior is unpredictable and difficult to troubleshoot.

I have so far been unable to find these deployment package definitions in Visual Studio 2008, nor have I found any part of the IDE that allows you to view or edit this.  This is a fundamental design flaw.  If you’re going to raise the level of abstraction, providing a way to make the guts visible and editable is essential for traceability and debugging, especially when the mechanism itself is flawed or is misused by third-party vendors.

For example, there is apparently some room for misinterpretation between where the CAB is located and where Visual Studio actually looks for it when deploying to a device.  When deploying a Symbol DLL file, Visual Studio notices that a Symbol deployment package exists, presumes it’s installed under the current Visual Studio directory (in my case, with Visual Studio 2008, it’s the directory Visual Studio 9.0), and proceeds to deploy from that location.  Unfortunately, the CAB file doesn’t actually exist there, so a deployment error results.

It looks here:

C:\Program Files\Microsoft Visual Studio 9.0\SmartDevices\SDK\Symbol Technologies

However, the SDK was actually installed here:

C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\Symbol Technologies

Error    1    Deployment and/or registration failed with error: 0x8973190d. Error opening file ‘C:\Program Files\Microsoft Visual Studio 9.0\smartdevices\sdk\Symbol Technologies\wce500\armv4i\symbol.all.arm.cab’. Error 0x80070003: The system cannot find the path specified.
      Device Connectivity Component  

Symbol’s .NET SDK v1.4 presumes you are using Visual Studio 2005, and installs itself into the Visual Studio 8.0 directory under Program Files.  This presumption is such an obviously bad practice, it simply shocks me.  They have their own install directory in “C:\Program Files\Symbol Mobility Developer Kit for .NET” where (a little deeper) they keep a copy of the CAB file, which exists independent of any tool that might use it (different versions of Visual Studio, SharpDevelop, etc.).

SQL Server CE / Compact has the same problem, depending on whether it gets installed with Visual Studio or is installed as a separate SDK.  I mentioned SQLCE SDK directory confusions in this article.

So take note: if you’re distributing an SDK, use a little common sense (and consistency) when deciding where to install it, and what presumptions you’re making about your audience.  Learn from SQLCE, Symbol, and others, what not to do.

Posted in Compact Framework, SQL Server Compact, Visual Studio | Leave a Comment »

Concurrency & Coordination With Futures in C#

Posted by Dan Vanderboom on July 3, 2008

A future is a proxy or placeholder for a value that may not yet be known, usually because the calculation is time consuming.  It is used as a synchronization construct, and it is an effective way to define dependencies among computations that will execute when all of their factors have been calculated, or in other words, to construct an expression tree with each node potentially computing in parallel.  According to the Wikipedia article on futures and promises, using them can dramatically reduce latency in distributed systems.

Damon pointed out that the Parallel Extensions library contains a Future<T> class, so I started looking around for examples and explanations of how they work, what the syntax is like, and I ran across a frightening example implementing the asynchronous programming model with Future<T>, as well as going in the other direction, wrapping an APM implementation with Future<T>.  Other articles give pretty good explanations but trivial examples.  From what I gathered briefly, the ContinueWith method for specifying the next step of calculation to process doesn’t seem to provide an intuitive way to indicate that several calculations may be depending upon the current one (unless it can be called multiple times?).  Using ContinueWith, you’re always specifying forward the calculation task that depends on the current future object.  It also surprised me a little that Future inherits from Task, because my understanding of a future is that it’s primarily defined as a value-holding object.  But considering that a future really holds an expression that needs to be calculated, making Future a Task doesn’t seem so odd.

So I decided to implement my own Future<T> class before looking at the parallel extensions library too deeply.  I didn’t want to prejudice my solution, because I wanted to make an exercise of it and see what I would naturally come up with.

Though I tried avoiding prejudice, I still wound up characterizing it in my head as an task, and thought that a future would simply be a pair of Action and Reaction methods (both of the Action delegate type).  The Action would execute and could do whatever it liked, including evaluate some expression and store it in a variable.  If the Action completed, the Reaction method (a continuation) would run, and these could be specified using lambdas.  Because I was storing the results in a local variable (result), swallowed up and made accessible with a closure, I didn’t see a need for a Value property in the future and therefore no need to make the type generic.  Ultimately I thought it silly to have a Reaction method, since anything you needed to happen sequentially after a successful Action, you could simply store at the end of the Action method itself.

FutureTask task = new FutureTask(
    () => result = CalculatePi(10),
    () => new FutureTask(
        () => result += "...",
        () => Console.WriteLine(result),
        ex2 => Console.WriteLine("ex2: " + ex2.Message)),
    ex1 => Console.WriteLine("ex1: " + ex1.Message));

The syntax is what I was most concerned with, and as I started playing around with nesting of futures to compose my calculation, I started to feel like I was onto something.  After all, it was almost starting to resemble some of the F# code I’ve been looking at, and I took that style of functional composition to be a good sign.  As you can see from the code above, I also include a constructor parameter of type Action<Exception> for compensation logic to run in the event that the original action fails.  (The result variable is a string, CalculatePi returns a string, and so the concatenation of the ellipsis really does make sense here.)

The problem that started nagging me was the thought that a composite computation of future objects might not be able to be defined all in one statement like this, not building the dependency tree from the bottom up.  You can really only define the most basic factors (the leaf nodes of a dependency tree) at the beginning this way, and then the expressions that depend directly upon those leaf nodes, etc.  What if you have 50 different starting future values, and you can only proceed with the next step in the calculation once 5 of those specific futures have completed evaluation?  How would you express those dependencies with this approach?

That’s when I started to think about futures as top-down hierarchical data container objects, instead of tasks that have pointers to some next task in a sequence.  I created a Future<T> class whose constructor takes an optional name (to aid debugging), a method of type Func<T> (which is a simple expression, supplied as a lambda in my examples), and finally an optional params list of other Future<T> objects on which that future value depends.

The first two futures in the code below start calculating pi (3.1415926535) and omega (which I made up to be a string of 9s).  They have no dependencies, so they can start calculating right away.  The paren future has two dependencies, supplied as two parameters at the end of the argument list: pi and omega.  You can see that the values pi.Value and omega.Value are used in the expression, which will simply surround the concatenated string value with parentheses and spaces.

var pi = new Future<string>("pi", () => CalculatePi(10));
var omega = new Future<string>("omega", () => CalculateOmega());

var paren = new Future<string>("parenthesize", () => Parenthesize(pi.Value + " < " + omega.Value), pi, omega);

var result = new Future<string>("bracket", () => Bracket(paren.Value), paren);

Finally, the result future has a dependency on the paren future.  This surrounds the result of paren.Value with brackets and spaces.  Because the operations here are trivial, I’ve added Thread.Sleep statements to all of these methods to simulate more computationally expensive work.

Dependencies Among Futures

The program starts calculating pi and omega concurrently, and then immediately builds the paren future, which because of its dependencies waits for completion of the pi and omega futures.  But it doesn’t block the thread.  Execution continues immediately to build the result future, and then moves on to the next part of the program.  When each part of the expression, each future, completes, it will set a Complete boolean property to true and invoke a Completed event.  Any attempt to access the Value property of one of these futures will block the thread until it (and all of the futures it depends on) have completed evaluation.

Furthermore, if an exception occurs, all of the futures that depend on it will no longer attempt to evaluate, and the exceptions will be thrown as part of an AggregateException when accessing the Value property.  This AggregateException contains all of the individual exceptions that were thrown as part of evaluating each future expression.  If both pi and omega fail, result should be able to hand me a list of all Exceptions below it in the tree structure that automatically gets formed.

There are two bits of code I added as icing on this cake.  The first is the use of the implicit operator to convert a variable of type Future<T> to type T.  In other words, if you have a Future<string> called result, you can now pass result into methods where a string parameter is expected, etc.  In the code listing at the end of the article, you’ll notice that I reference pi and omega instead of pi.Value and omega.Value (as in the code snippet above).

public static implicit operator T(Future<T> Future)
{
    return Future.Value;
}

The other helpful bit is an override of ToString, which allows you to hover over a future variable in debug mode and see its name (if you named it), whether it’s Complete or Incomplete, and any errors encountered during evaluation.

public override string ToString()
{
    return Name + ", " + (Complete ? "Complete" : "Incomplete") + (Error != null ? "Error=" + Error.Message : string.Empty);
}

Debug Experience of Future

What I’d really like to do is have the ability to construct this composite expression in a hierarchical form in the language, with a functionally composed syntax, replacing any parameter T with a Future<T>, something like this:

var result = new Future<string>("bracket", () => Bracket(
    new Future<string>("parenthesize", () => Parenthesize(
        new Future<string>("pi", () => CalculatePi(10))
        + " < " +
        new Future<string>("omega", () => CalculateOmega())
    ))
));

The Bracket and Parenthesize methods both require a string, but I give them an object that will at some point (“in the future”) evaluate to a string.  Another term used for future is promise, although there is a distinction in some languages that support both, but you can think in terms of giving those methods the promise that they’ll get a string later, at which time they can proceed with their own evaluation.  This effectively creates lazy evaluation, sometimes referred to as normal-order evaluation.

There are a few problems with this code, however.  First of all, though it’s composed functionally from the top down and returns the correct answer, it takes too long to do it: about 8 seconds instead of 4.  That means it’s processing all of the steps sequentially.  This happens because the future objects we’re handing to the Parenthesize and Bracket methods have to be converted from Future<string> to string before they can be evaluated in the expression, and doing that activates the implicit operator, which executes the Value property getter.  This completely destroys the asynchronous behavior we’re going for, by insisting on resolving it immediately with the wait built-into the Value property.  The string concatenation expression evaluates sequentially one piece at a time, and when that’s done, the next level up evaluates, and so on.

The solution is to declare our futures as factors we depend on at each level, which start them executing right away due to C#’s order of evaluation, and declare the operations we want to perform in terms of those predefined futures.  After a few hours of rearranging definitions, declaration order, and experimenting with many other details (including a brief foray into being more indirect with Func<Future<T>>), this is the working code I came up with:

Future<string> FuturePi = null, FutureOmega = null, FutureConcat = null, FutureParen = null;

var result = new Future<string>(
    () => Bracket(FutureParen),
    (FutureParen = new Future<string>(
        () => Parenthesize(FutureConcat),
        (FutureConcat = new Future<String>(
            () => FuturePi + " < " + FutureOmega,
            (FuturePi = new Future<string>(() => CalculatePi(10))),
            (FutureOmega = new Future<string>(() => CalculateOmega()))
        ))
    ))
);

In F# and other more functional languages, I imagine we could use let statements to define and assign these variables as part of the overall expression, instead of having to define the variables in a separate statement as shown here.

The Future<T> class I wrote works fairly well for exploration and study of futures and the possible syntax to define them and access their values, and I’ll share it so that you can experiment with it if you like, but understand that this is (even more so than usual) not production ready code.  I’m making some very naive assumptions, not taking advantage of any task managers or thread pools, there is no intelligent scheduling going on, and I haven’t tested this in any real world applications.  With that disclaimer out of the way, here it is, complete with the consuming test code.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Linq;

namespace FutureExpressionExample
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime StartTime = DateTime.Now;

            Future<string> FuturePi = null, FutureOmega = null, FutureConcat = null, FutureParen = null;

            var result = new Future<string>("bracket",
                () => Bracket(FutureParen),
                (FutureParen = new Future<string>("parenthesize",
                    () => Parenthesize(FutureConcat),
                    (FutureConcat = new Future<String>("concat",
                        () => FuturePi + " < " + FutureOmega,
                        (FuturePi = new Future<string>("pi", () => CalculatePi(10))),
                        (FutureOmega = new Future<string>("omega", () => CalculateOmega()))
                    ))
                ))
            );

            /* Alternative
             
            // first group of expressions evaluating in parallel
            var pi = new Future<string>("pi", () => CalculatePi(10));
            var omega = new Future<string>("omega", () => CalculateOmega());

            // a single future expression dependent on all of the futures in the first group
            var paren = new Future<string>("parenthesize", () => Parenthesize(pi + " < " + omega), pi, omega);
                        
            // another single future expression dependent on the paren future
            var result = new Future<string>("bracket", () => Bracket(paren), paren);

            */

            Console.WriteLine("Do other stuff while calculation occurs...");

            try
            {
                Console.WriteLine("\n" + result);
            }
            catch (AggregateException ex)
            {
                Console.WriteLine("\n" + ex.Message);
            }

            TimeSpan ts = DateTime.Now - StartTime;
            Console.WriteLine("\n" + ts.TotalSeconds.ToString() + " seconds");

            Console.ReadKey();
        }

        static string CalculatePi(int NumberDigits)
        {
            //throw new ApplicationException("Failed to calculate Pi");
            Thread.Sleep(3000);
            return "3.1415926535";
        }

        static string CalculateOmega()
        {
            //throw new ApplicationException("Failed to calculate Omega");
            Thread.Sleep(3000);
            return "999999999999999";
        }

        static string Parenthesize(string Text)
        {
            Thread.Sleep(500);
            return "( " + Text + " )";
        }

        static string Bracket(string Text)
        {
            Thread.Sleep(500);
            return "[ " + Text + " ]";
        }
    }

    public class Future<T> : IDisposable
    {
        public string Name { get; set; }
        public bool Complete { get; protected set; }
        public Exception Error { get; protected set; }

        protected Func<T> Expression { get; set; }

        protected List<Future<T>> Factors;
        protected List<Future<T>> FactorsCompleted;
        protected List<Future<T>> FactorsFailed;

        public event Action<Future<T>> Completed;
        protected void OnCompleted()
        {
            Complete = true;

            if (Completed != null)
                Completed(this);
        }

        private T _Value;
        public T Value
        {
            get
            {
                // block until complete
                while (!Complete)
                {
                    Thread.Sleep(1);
                }

                if (Exceptions.Count > 0)
                    throw new AggregateException(Exceptions);

                return _Value;
            }
            private set { _Value = value; }
        }

        public List<Exception> Exceptions
        {
            get
            {
                var list = new List<Exception>();

                foreach (Future<T> Factor in Factors)
                {
                    list.AddRange(Factor.Exceptions);
                }

                if (Error != null)
                    list.Add(Error);

                return list;
            }
        }

        public static implicit operator T(Future<T> Future)
        {
            return Future.Value;
        }

        // naming a Future is optional
        public Future(Func<T> Expression, params Future<T>[] Factors) : this("<not named>", Expression, Factors) { }

        public Future(string Name, Func<T> Expression, params Future<T>[] Factors)
        {
            this.Name = Name;
            this.Expression = Expression;
            this.Factors = new List<Future<T>>(Factors);
            
            FactorsCompleted = new List<Future<T>>();
            FactorsFailed = new List<Future<T>>();

            foreach (Future<T> Factor in this.Factors)
            {
                if (Factor.Complete)
                    FactorsCompleted.Add(Factor);
                else
                    Factor.Completed += new Action<Future<T>>(Factor_Completed);
            }

            // there may not be any factors, or they may all be complete
            if (FactorsCompleted.Count == this.Factors.Count)
                Expression.BeginInvoke(ReceiveCallback, null);
        }

        private void Factor_Completed(Future<T> Factor)
        {
            if (!FactorsCompleted.Contains(Factor))
                FactorsCompleted.Add(Factor);

            if (Factor.Error != null && !FactorsFailed.Contains(Factor))
                FactorsFailed.Add(Factor);

            Factor.Completed -= new Action<Future<T>>(Factor_Completed);

            if (Exceptions.Count > 0)
            {
                Dispose();
                OnCompleted();
                return;
            }

            if (FactorsCompleted.Count == Factors.Count)
                Expression.BeginInvoke(ReceiveCallback, null);
        }

        private void ReceiveCallback(IAsyncResult AsyncResult)
        {
            try
            {
                Value = Expression.EndInvoke(AsyncResult);
            }
            catch (Exception ex)
            {
                Error = ex;
            }
            
            Dispose();

            // computation is completed, regardless of whether it succeeded or failed
            OnCompleted();
        }

        public void Dispose()
        {
            foreach (Future<T> Factor in Factors)
            {
                Factor.Completed -= new Action<Future<T>>(Factor_Completed);
            }
        }

        // helpful for debugging
        public override string ToString()
        {
            return Name + ", " + (Complete ? "Complete" : "Incomplete") + (Error != null ? ", Error=" + Error.Message : string.Empty);
        }
    }

    public class AggregateException : Exception
    {
        public List<Exception> Exceptions;

        public AggregateException(IEnumerable<Exception> Exceptions)
        {
            this.Exceptions = new List<Exception>(Exceptions);
        }

        public override string Message
        {
            get
            {
                string message = string.Empty;
                foreach (Exception ex in Exceptions)
                {
                    message += ex.Message + "\n";
                }
                return message;
            }
        }
    }
}

Posted in Algorithms, Concurrency, Data Structures, Design Patterns, Functional Programming | 1 Comment »

Control Invoke Pattern Using Lambdas

Posted by Dan Vanderboom on July 1, 2008

In Windows Forms development, there are often times when you need to update the user interface in response to something happening on another thread.  This could be a timer firing every second, some service running in the background and notifying the client of updated status on its own (background) thread, etc.  If you’ve been working with Windows Forms for any length of time, you’ve doubtless run into exceptions that kindly inform you that you can’t update controls on a thread other than the one that created those controls. We’ll consider the simple issue of a timer firing every second, and the display of elapsed time in a label, for our example here, and introduce a new pattern to make this cleaner and more intuitive.

First we’ll set up our start time and the thread.  I use the System.Threading.Timer to ensure that we’re using a non-UI thread.

StartTime = DateTime.Now;

Timer = new System.Threading.Timer(new TimerCallback(Timer_Tick));
Timer.Change(0, 1000);

Here’s the event handler that calculates the elapsed time and calls Invoke, as well as the method we’re invoking, which will run on the UI thread, where it can safely update the lblElapsedTime label control.

private void Timer_Tick(object state)
{
    TimeSpan ts = DateTime.Now - StartTime;
    Invoke(new StringDelegate(DisplayText), ts.TotalSeconds.ToString());
}

private void DisplayText(string Text)
{
    lblElapsedTime.Text = Text;
}

In order to make this work, we need the event handler, a separate method to run in the UI thread, and also a delegate that matches the invoked method.

public delegate void StringDelegate(string Text);

This is a lot of moving parts for such a small piece of functionality.  To make matters worse, you may need to repeat this pattern many times, depending on the controls (or combinations thereof) that you need to update.  In a modern multi-threaded application, your class can become littered with these invocations, handlers, and delegates.

What I’d really like to do is call Invoke and pass in an anonymous method (in lambda form).  Unfortunately, Invoke takes a Delegate parameter, which is an abstract type.  This forces you to instantiate a concrete delegate type.  So while we eliminate our need for a separate method, we’re still dependent on our delegate type.

private void Timer_Tick(object state)
{
    TimeSpan ts = DateTime.Now - StartTime;
    Invoke(new StringDelegate(s => lblElapsedTime.Text = s), ts.TotalSeconds.ToString());
}

Or are we?  By using the Action (or MethodInvoker) delegate for all of these invocations, and relying on C# and its support for closures, we can make a reference to the TimeSpan variable from within the anonymous method body, like this:

private void Timer_Tick(object state)
{
    TimeSpan ts = DateTime.Now - StartTime;
    Invoke(new Action(() => lblElapsedTime.Text = ts.TotalSeconds.ToString()));
}

Here it’s contained within a single method, and no additional delegates will be necessary to make this work.  That’s pretty nice!  (A similar approach is taken here.)  But it’s still not quite as slick and intuitive as I’d like.  By creating an extension method, adding another overload of Invoke to the Control class, we can allow Invoke to assume a concrete Action delegate class, and write code like this:

private void Timer_Tick(object state)
{
    TimeSpan ts = DateTime.Now - StartTime;
    this.Invoke(() => lblElapsedTime.Text = ts.TotalSeconds.ToString());
}

Now that’s clean.  Just call Invoke, and pass in the lambda to execute.  Or several statements in a code block if you like.  It’s very succinct.  The only part that bothers me is the this keyword that’s required.  Extension methods don’t register in Intellisense, nor do they compile successfully, if they’re used without a variable, this, base, or something else with a dot after them.  If we’re really going to push the illusion of extending a class, I think we need to go all the way and make it work without having to explicitly type this.  But it is what it is for now; hopefully this will be fixed in the next version of C# (along with adding support for extension properties, events, and operators).

That being said, here is the extension method to make this work:

public static void Invoke(this Control Control, Action Action)
{
    Control.Invoke(Action);
}

It couldn’t be simpler (thanks to a little help from Mads Torgersen)!  I’ll include the finished program for those of you who want to run it to see and experiment; you’ll just need to create the Program.cs with the startup code yourself.  Create a new Windows Forms app and use what’s there, renaming the form listed in Application.Run to match this one.

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;

namespace ControlInvokeLambda
{
    public partial class frmTestInvokeLambda : Form
    {
        private Button btnExit;
        private Label lblElapsedTime;

        // make sure we're using the Threading Timer for our example, which runs on a non-UI thread
        private System.Threading.Timer Timer;
        
        private DateTime StartTime;

        public frmTestInvokeLambda()
        {
            // initialize controls
            
            btnExit = new Button();
            btnExit.Location = new Point(88, 80);
            btnExit.Name = "btnExit";
            btnExit.Size = new Size(118, 26);
            btnExit.TabIndex = 0;
            btnExit.Text = "Exit";
            btnExit.UseVisualStyleBackColor = true;
            btnExit.Click += new EventHandler(this.btnExit_Click);

            lblElapsedTime = new Label();
            lblElapsedTime.AutoSize = true;
            lblElapsedTime.Location = new Point(140, 36);
            lblElapsedTime.Name = "lblElapsedTime";
            lblElapsedTime.Size = new Size(13, 13);
            lblElapsedTime.TabIndex = 1;
            lblElapsedTime.Text = "0";

            AutoScaleDimensions = new SizeF(6F, 13F);
            AutoScaleMode = AutoScaleMode.Font;
            ClientSize = new Size(292, 136);
            Controls.Add(lblElapsedTime);
            Controls.Add(btnExit);
            Name = "frmTestInvokeLambda";
            Text = "Invoke Lambda";
            PerformLayout();

            // remember start time and startup timer

            StartTime = DateTime.Now;

            Timer = new System.Threading.Timer(new TimerCallback(Timer_Tick));
            Timer.Change(0, 1000);
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Timer.Change(Timeout.Infinite, Timeout.Infinite);
            Application.Exit();
        }

        private void Timer_Tick(object state)
        {
            TimeSpan ts = DateTime.Now - StartTime;
            this.Invoke(() => lblElapsedTime.Text = ts.TotalSeconds.ToString());
        }
    }

    public static class ControlExtensions
    {
        public static void Invoke(this Control Control, Action Action)
        {
            Control.Invoke(Action);
        }
    }
}

Posted in Algorithms, Concurrency, Design Patterns, Windows Forms | 2 Comments »