Friday, September 27, 2013

Proof that using Single(float), or Double(double) is bad for money calculations.

namespace Console42 {
    using System;
 
    class Program {
        static void Main( string[] args ) {
 
            //Proof that using Single(float), or Double(double) is bad for money calculations.
            double x = 0.1;
            double y = x + x + x;
            Console.WriteLine( y == 0.3 ); // Prints False
 
            Console.WriteLine( Math.Abs( y - 0.3 ) < double.Epsilon ); // Prints False
 
        }
    }
}

C#: BigDecimal class ( from StackOverflow )


    /// <summary>
    ///     Arbitrary precision Decimal.
    ///     All operations are exact, except for division. Division never determines more digits than the given precision.
    ///     Based on http://stackoverflow.com/a/4524254
    ///     Author: Jan Christoph Bernack (contact: jc.bernack at googlemail.com)
    /// </summary>
    /// <see cref="http://stackoverflow.com/a/13813535/956364" />
    [UsedImplicitly]
    public struct BigDecimal : IComparable, IComparable< BigDecimal > {
        /// <summary>
        ///     Sets the maximum precision of division operations.
        ///     If AlwaysTruncate is set to true all operations are affected.
        /// </summary>
        public const int Precision = 50;
 
        public BigDecimal( BigDecimal bigDecimal, Boolean alwaysTruncate = false ) : this( bigDecimal.Mantissa, bigDecimal.Exponent, alwaysTruncate ) { }
 
        public BigDecimal( Decimal value, Boolean alwaysTruncate = false ) : this( ( BigDecimal ) value, alwaysTruncate ) { }
 
        /// <summary>
        /// </summary>
        /// <param name="mantissa"></param>
        /// <param name="exponent"></param>
        /// <param name="alwaysTruncate">
        ///     Specifies whether the significant digits should be truncated to the given precision after
        ///     each operation.
        /// </param>
        public BigDecimal( BigInteger mantissa, int exponent, Boolean alwaysTruncate = false ) : this() {
            this.Mantissa = mantissa;
            this.Exponent = exponent;
            this.Normalize();
            if ( alwaysTruncate ) {
                this.Truncate();
            }
        }
 
        public BigInteger Mantissa { get; set; }
        public int Exponent { get; set; }
 
        public int CompareTo( object obj ) {
            if ( ReferenceEquals( obj, null ) || !( obj is BigDecimal ) ) {
                throw new ArgumentException();
            }
            return this.CompareTo( ( BigDecimal ) obj );
        }
 
        public int CompareTo( BigDecimal other ) {
            return this < other ? -1 : ( this > other ? 1 : 0 );
        }
 
        /// <summary>
        ///     Removes trailing zeros on the mantissa
        /// </summary>
        public void Normalize() {
            if ( this.Mantissa.IsZero ) {
                this.Exponent = 0;
            }
            else {
                BigInteger remainder = 0;
                while ( remainder == 0 ) {
                    var shortened = BigInteger.DivRem( dividend: this.Mantissa, divisor: 10, remainder: out remainder );
                    if ( remainder != 0 ) {
                        continue;
                    }
                    this.Mantissa = shortened;
                    this.Exponent++;
                }
            }
        }
 
        /// <summary>
        ///     Truncate the number to the given precision by removing the least significant digits.
        /// </summary>
        /// <returns>The truncated number</returns>
        public BigDecimal Truncate( int precision = Precision ) {
            // copy this instance (remember its a struct)
            var shortened = this;
            // save some time because the number of digits is not needed to remove trailing zeros
            shortened.Normalize();
            // remove the least significant digits, as long as the number of digits is higher than the given Precision
            while ( NumberOfDigits( shortened.Mantissa ) > precision ) {
                shortened.Mantissa /= 10;
                shortened.Exponent++;
            }
            return shortened;
        }
 
        private static int NumberOfDigits( BigInteger value ) {
            // do not count the sign
            return ( value*value.Sign ).ToString()
                                       .Length;
        }
 
        public override string ToString() {
            return string.Concat( this.Mantissa.ToString(), "E", this.Exponent );
        }
 
        public bool Equals( BigDecimal other ) {
            return other.Mantissa.Equals( this.Mantissa ) && other.Exponent == this.Exponent;
        }
 
        public override bool Equals( [CanBeNull] object obj ) {
            if ( ReferenceEquals( null, obj ) ) {
                return false;
            }
            return obj is BigDecimal && this.Equals( ( BigDecimal ) obj );
        }
 
        public override int GetHashCode() {
            unchecked {
                return ( this.Mantissa.GetHashCode()*397 ) ^ this.Exponent;
            }
        }
 
        #region Conversions
        public static implicit operator BigDecimal( int value ) {
            return new BigDecimal( value, 0 );
        }
 
        public static implicit operator BigDecimal( double value ) {
            var mantissa = ( BigInteger ) value;
            var exponent = 0;
            double scaleFactor = 1;
            while ( Math.Abs( value*scaleFactor - ( double ) mantissa ) > 0 ) {
                exponent -= 1;
                scaleFactor *= 10;
                mantissa = ( BigInteger ) ( value*scaleFactor );
            }
            return new BigDecimal( mantissa, exponent );
        }
 
        public static implicit operator BigDecimal( Decimal value ) {
            var mantissa = ( BigInteger ) value;
            var exponent = 0;
            Decimal scaleFactor = 1;
            while ( ( Decimal ) mantissa != value*scaleFactor ) {
                exponent -= 1;
                scaleFactor *= 10;
                mantissa = ( BigInteger ) ( value*scaleFactor );
            }
            return new BigDecimal( mantissa, exponent );
        }
 
        public static explicit operator double( BigDecimal value ) {
            return ( double ) value.Mantissa*Math.Pow( 10, value.Exponent );
        }
 
        public static explicit operator float( BigDecimal value ) {
            return Convert.ToSingle( ( double ) value );
        }
 
        public static explicit operator Decimal( BigDecimal value ) {
            return ( Decimal ) value.Mantissa*( Decimal ) Math.Pow( 10, value.Exponent );
        }
 
        public static explicit operator int( BigDecimal value ) {
            return ( int ) ( value.Mantissa*BigInteger.Pow( 10, value.Exponent ) );
        }
 
        public static explicit operator uint( BigDecimal value ) {
            return ( uint ) ( value.Mantissa*BigInteger.Pow( 10, value.Exponent ) );
        }
        #endregion
 
        #region Operators
        public static BigDecimal operator +( BigDecimal value ) {
            return value;
        }
 
        public static BigDecimal operator -( BigDecimal value ) {
            value.Mantissa *= -1;
            return value;
        }
 
        public static BigDecimal operator ++( BigDecimal value ) {
            return value + 1;
        }
 
        public static BigDecimal operator --( BigDecimal value ) {
            return value - 1;
        }
 
        public static BigDecimal operator +( BigDecimal left, BigDecimal right ) {
            return Add( left, right );
        }
 
        public static BigDecimal operator -( BigDecimal left, BigDecimal right ) {
            return Add( left, -right );
        }
 
        private static BigDecimal Add( BigDecimal left, BigDecimal right ) {
            return left.Exponent > right.Exponent ? new BigDecimal( AlignExponent( left, right ) + right.Mantissa, right.Exponent ) : new BigDecimal( AlignExponent( right, left ) + left.Mantissa, left.Exponent );
        }
 
        public static BigDecimal operator *( BigDecimal left, BigDecimal right ) {
            return new BigDecimal( left.Mantissa*right.Mantissa, left.Exponent + right.Exponent );
        }
 
        public static BigDecimal operator /( BigDecimal dividend, BigDecimal divisor ) {
            var exponentChange = Precision - ( NumberOfDigits( dividend.Mantissa ) - NumberOfDigits( divisor.Mantissa ) );
            if ( exponentChange < 0 ) {
                exponentChange = 0;
            }
            dividend.Mantissa *= BigInteger.Pow( 10, exponentChange );
            return new BigDecimal( dividend.Mantissa/divisor.Mantissa, dividend.Exponent - divisor.Exponent - exponentChange );
        }
 
        public static bool operator ==( BigDecimal left, BigDecimal right ) {
            return left.Exponent == right.Exponent && left.Mantissa == right.Mantissa;
        }
 
        public static bool operator !=( BigDecimal left, BigDecimal right ) {
            return left.Exponent != right.Exponent || left.Mantissa != right.Mantissa;
        }
 
        public static bool operator <( BigDecimal left, BigDecimal right ) {
            return left.Exponent > right.Exponent ? AlignExponent( left, right ) < right.Mantissa : left.Mantissa < AlignExponent( right, left );
        }
 
        public static bool operator >( BigDecimal left, BigDecimal right ) {
            return left.Exponent > right.Exponent ? AlignExponent( left, right ) > right.Mantissa : left.Mantissa > AlignExponent( right, left );
        }
 
        public static bool operator <=( BigDecimal left, BigDecimal right ) {
            return left.Exponent > right.Exponent ? AlignExponent( left, right ) <= right.Mantissa : left.Mantissa <= AlignExponent( right, left );
        }
 
        public static bool operator >=( BigDecimal left, BigDecimal right ) {
            return left.Exponent > right.Exponent ? AlignExponent( left, right ) >= right.Mantissa : left.Mantissa >= AlignExponent( right, left );
        }
 
        /// <summary>
        ///     Returns the mantissa of value, aligned to the exponent of reference.
        ///     Assumes the exponent of value is larger than of value.
        /// </summary>
        private static BigInteger AlignExponent( BigDecimal value, BigDecimal reference ) {
            return value.Mantissa*BigInteger.Pow( 10, value.Exponent - reference.Exponent );
        }
        #endregion
 
        #region Additional mathematical functions
        public static BigDecimal Exp( double exponent ) {
            var tmp = ( BigDecimal ) 1;
            while ( Math.Abs( exponent ) > 100 ) {
                var diff = exponent > 0 ? 100 : -100;
                tmp *= Math.Exp( diff );
                exponent -= diff;
            }
            return tmp*Math.Exp( exponent );
        }
 
        public static BigDecimal Pow( double basis, double exponent ) {
            var tmp = ( BigDecimal ) 1;
            while ( Math.Abs( exponent ) > 100 ) {
                var diff = exponent > 0 ? 100 : -100;
                tmp *= Math.Pow( basis, diff );
                exponent -= diff;
            }
            return tmp*Math.Pow( basis, exponent );
        }
        #endregion
    }

Thursday, September 26, 2013

C#: Get all derived Types from the base Type that should be able to be created via Activator.CreateInstance


        /// <summary>
        /// Get all <see cref="Type"/> from <see cref="AppDomain.CurrentDomain"/> that should be able to be created via <see cref="Activator.CreateInstance(System.Type,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo) "/>.
        /// </summary>
        /// <param name="baseType"></param>
        /// <returns></returns>
        public static IEnumerable< Type > GetTypesDerivedFrom( [CanBeNull] this Type baseType ) {
            if ( baseType == null ) {
                throw new ArgumentNullException( "baseType" );
            }
            return AppDomain.CurrentDomain.GetAssemblies()
                            .SelectMany( assembly => assembly.GetTypes(), ( assembly, type ) => type )
                            .Where( arg => baseType.IsAssignableFrom( arg ) && arg.IsClass && !arg.IsAbstract );
        }

C#: Return each DateTime between @from and @to, stepped by a TimeSpan


        /// <summary>
        ///     Return each <see cref="DateTime" /> between <paramref name="from" /> and <paramref name="to" />, stepped by a
        ///     <see cref="TimeSpan" /> (<paramref name="step" />).
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="step"></param>
        /// <returns></returns>
        /// <remarks>//TODO Untested code!</remarks>
        /// <example>
        ///     var now = DateTime.UtcNow;
        ///     var then = now.AddMinutes( 10 );
        ///     var minutes = now.To( then, TimeSpan.FromMinutes( 1 ) );
        ///     foreach ( var dateTime in minutes ) { Console.WriteLine( dateTime ); }
        /// </example>
        public static IEnumerable<DateTime> To( this DateTime from, DateTime to, TimeSpan? step = null ) {
            if ( !step.HasValue ) {
                try {
                    var diff = @from <= to ? to.Subtract( @from ) : @from.Subtract( @from );
 
                    if ( diff.TotalDays > 0 ) {
                        step = TimeSpan.FromDays( 1 );
                    }
                    else if ( diff.TotalHours > 0 ) {
                        step = TimeSpan.FromHours( 1 );
                    }
                    else if ( diff.TotalMinutes > 0 ) {
                        step = TimeSpan.FromMinutes( 1 );
                    }
                    else if ( diff.TotalSeconds > 0 ) {
                        step = TimeSpan.FromSeconds( 1 );
                    }
                    else {
                        step = TimeSpan.FromMilliseconds( 1 );
                    }
                }
                catch ( ArgumentOutOfRangeException ) {
                    step = TimeSpan.MaxValue;
                }
            }
 
            if ( from <= to ) {
                for ( var dt = from; dt <= to; dt += step.Value ) {
                    yield return dt;
                }
            }
            else {
                for ( var dt = from; dt >= to; dt -= step.Value ) {
                    yield return dt;
                }
            }
        }

C#: Return true if an IComparable value is Between two inclusive values.

        /// <summary>
        ///     Return true if an <see cref="IComparable"/> value is <see cref="Between{T}"/> two inclusive values.
        /// </summary>
        /// <typeparam name="T"> </typeparam>
        /// <param name="target"> </param>
        /// <param name="startInclusive"> </param>
        /// <param name="endInclusive"> </param>
        /// <returns> </returns>
        /// <example>5.Between(1, 10) == true</example>
        /// <example>5.Between(10, 1) == true</example>
        /// <example>5.Between(10, 6) == false</example>
        /// <example>5.Between(5, 5)) == true</example>
        public static Boolean Between<T>( this T target, T startInclusive, T endInclusive ) where T : IComparable {
            return startInclusive.CompareTo( endInclusive ) == 1 ? ( target.CompareTo( startInclusive ) <= 0 ) && ( target.CompareTo( endInclusive ) >= 0 ) : ( target.CompareTo( startInclusive ) >= 0 ) && ( target.CompareTo( endInclusive ) <= 0 );
        }

C#: ForEach with an IEnumerable range of UInt64 (ulong) values


        /// <summary>
        ///     Example: foreach (var i in 10240.To(20448)) { Console.WriteLine(i); }
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="step"></param>
        /// <returns></returns>
        public static IEnumerable<UInt64> To( this int from, UInt64 to, UInt64 step = 1 ) {
            if ( from < 0 ) {
                throw new ArgumentOutOfRangeException( "from", "From must be equal to or greater than zero." );
            }
 
            if ( step == 0UL ) {
                step = 1UL;
            }
 
            var reFrom = ( UInt64 )from;        //bug here is the bug if from is less than zero
 
            if ( from <= ( decimal )to ) {
                for ( var ul = reFrom; ul <= to; ul += step ) {
                    yield return ul;
                    if ( ul == UInt64.MaxValue ) { yield break; }   //special case to deal with overflow
                }
            }
            else {
                for ( var ul = reFrom; ul >= to; ul -= step ) {
                    yield return ul;
                    if ( ul == UInt64.MinValue ) { yield break; }   //special case to deal with overflow
                }
            }
        }
 
        /// <summary>
        ///     Example: foreach (var i in 10240.To(20448)) { Console.WriteLine(i); }
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="step"></param>
        /// <returns></returns>
        public static IEnumerable<UInt64> To( this UInt64 from, UInt64 to, UInt64 step = 1 ) {
            if ( step == 0UL ) {
                step = 1UL;
            }
 
            if ( from <= to ) {
                for ( var ul = from; ul <= to; ul += step ) {
                    yield return ul;
                    if ( ul == UInt64.MaxValue ) { yield break; }   //special case to deal with overflow
                }
            }
            else {
                for ( var ul = from; ul >= to; ul -= step ) {
                    yield return ul;
                    if ( ul == UInt64.MinValue ) { yield break; }   //special case to deal with overflow
                }
            }
        }

Tuesday, September 24, 2013

C#: When To Use Parallel.ForEach() Or AsParallel()

Conclusion: 
Parallel.ForEach() is intended for simple data with independent actions.
ForAll() is intended to be used at the end of a (possibly complex) PLINQ query.

Thanks to svick on StackOverflow for answering this.

Sunday, September 22, 2013

C#: String interning and String.Empty - Fabulous Adventures In Coding - Site Home - MSDN Blogs

"...Surely if A equals B, and B equals C, then A equals C; that's the transitive property of equality. It appears to have been thoroughly violated here..."

Potential Pitfalls with PLINQ (from Microsoft)

Highlights from Microsoft (thank you Microsoft!):

Potential Pitfalls with PLINQ

.NET Framework 4.5
In many cases, PLINQ can provide significant performance improvements over sequential LINQ to Objects queries. However, the work of parallelizing the query execution introduces complexity that can lead to problems that, in sequential code, are not as common or are not encountered at all. 
Do Not Assume That Parallel Is Always Faster


Parallelization sometimes causes a PLINQ query to run slower than its LINQ to Objects equivalent. The basic rule of thumb is that queries that have few source elements and fast user delegates are unlikely to speedup much.
Avoid Writing to Shared Memory Locations


Whenever multiple threads are accessing such variables concurrently, there is a big potential for race conditions. Even though you can use locks to synchronize access to the variable, the cost of synchronization can hurt performance. Therefore, we recommend that you avoid, or at least limit, access to shared state in a PLINQ query as much as possible.
Avoid Over-Parallelization


By using the AsParallel operator, you incur the overhead costs of partitioning the source collection and synchronizing the worker threads. The benefits of parallelization are further limited by the number of processors on the computer. There is no speedup to be gained by running multiple compute-bound threads on just one processor. Therefore, you must be careful not to over-parallelize a query.
The most common scenario in which over-parallelization can occur is in nested queries, as shown in the following snippet.
var q = from cust in customers.AsParallel()
        from order in cust.Orders.AsParallel()
        where order.OrderDate > date
        select new { cust, order };
In this case, it is best to parallelize only the outer data source (customers) unless one or more of the following conditions apply:
  • The inner data source (cust.Orders) is known to be very long.
  • You are performing an expensive computation on each order. (The operation shown in the example is not expensive.)
  • The target system is known to have enough processors to handle the number of threads that will be produced by parallelizing the query on cust.Orders.

Avoid Calls to Non-Thread-Safe Methods
Writing to non-thread-safe instance methods from a PLINQ query can lead to data corruption which may or may not go undetected in your program.
FileStream fs = File.OpenWrite(...);
a.Where(...).OrderBy(...).Select(...).ForAll(x => fs.Write(x));
Limit Calls to Thread-Safe Methods


Most static methods in the .NET Framework are thread-safe and can be called from multiple threads concurrently. However, even in these cases, the synchronization involved can lead to significant slowdown in the query.
Note Note
You can test for this yourself by inserting some calls to WriteLine in your queries. Although this method is used in the documentation examples for demonstration purposes, do not use it in PLINQ queries.
Avoid Unnecessary Ordering Operations


When PLINQ executes a query in parallel, it divides the source sequence into partitions that can be operated on concurrently on multiple threads. By default, the order in which the partitions are processed and the results are delivered is not predictable (except for operators such as OrderBy). You can instruct PLINQ to preserve the ordering of any source sequence, but this has a negative impact on performance. The best practice, whenever possible, is to structure queries so that they do not rely on order preservation. For more information, see Order Preservation in PLINQ.
Prefer ForAll to ForEach When It Is Possible


Although PLINQ executes a query on multiple threads, if you consume the results in a foreach loop (For Each in Visual Basic), then the query results must be merged back into one thread and accessed serially by the enumerator. In some cases, this is unavoidable; however, whenever possible, use the ForAll method to enable each thread to output its own results, for example, by writing to a thread-safe collection such asSystem.Collections.Concurrent.ConcurrentBag<T>.
The same issue applies to Parallel.ForEach In other words, source.AsParallel().Where().ForAll(...) should be strongly preferred to
Parallel.ForEach(source.AsParallel().Where(), ...).
Be Aware of Thread Affinity Issues


Some technologies, for example, COM interoperability for Single-Threaded Apartment (STA) components, Windows Forms, and Windows Presentation Foundation (WPF), impose thread affinity restrictions that require code to run on a specific thread. For example, in both Windows Forms and WPF, a control can only be accessed on the thread on which it was created. If you try to access the shared state of a Windows Forms control in a PLINQ query, an exception is raised if you are running in the debugger. (This setting can be turned off.) However, if your query is consumed on the UI thread, then you can access the control from the foreach loop that enumerates the query results because that code executes on just one thread.
Do Not Assume that Iterations of ForEach, For and ForAll Always Execute in Parallel


It is important to keep in mind that individual iterations in a Parallel.ForParallel.ForEach or ForAll<TSource> loop may but do not have to execute in parallel. Therefore, you should avoid writing any code that depends for correctness on parallel execution of iterations or on the execution of iterations in any particular order.
For example, this code is likely to deadlock:
ManualResetEventSlim mre = new ManualResetEventSlim();
            Enumerable.Range(0, ProcessorCount * 100).AsParallel().ForAll((j) =>
            {
                if (j == Environment.ProcessorCount)
                {
                    Console.WriteLine("Set on {0} with value of {1}", Thread.CurrentThread.ManagedThreadId, j);
                    mre.Set();
                }
                else
                {
                    Console.WriteLine("Waiting on {0} with value of {1}", Thread.CurrentThread.ManagedThreadId, j);
                    mre.Wait();
                }
            }); //deadlocks
In this example, one iteration sets an event, and all other iterations wait on the event. None of the waiting iterations can complete until the event-setting iteration has completed. However, it is possible that the waiting iterations block all threads that are used to execute the parallel loop, before the event-setting iteration has had a chance to execute. This results in a deadlock – the event-setting iteration will never execute, and the waiting iterations will never wake up.
In particular, one iteration of a parallel loop should never wait on another iteration of the loop to make progress. If the parallel loop decides to schedule the iterations sequentially but in the opposite order, a deadlock will occur.

C#: How to get the current battery level in C#

PowerStatus p = SystemInformation.PowerStatus;

C#: Perform the action on the thread the Control was created.


        /// <summary>
        /// Perform the action on the thread the <see cref="Control"/> was created.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="action"></param>
        public static void InvokeIfRequired( this Control control, Action action ) {
            if ( control.InvokeRequired ) {
                control.BeginInvoke( action );
            }
            else {
                action();
            }
        }

Saturday, September 21, 2013

C#: Safely set the Enabled and Visible of a Control across threads.


        /// <summary>
        ///     Safely set the <see cref="Control.Enabled" /> and <see cref="Control.Visible" /> of a control across threads.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="value"></param>
        public static void Usable( this Control control, Boolean value ) {
            if ( null == control ) {
                return;
            }
            if ( control.InvokeRequired ) {
                control.BeginInvoke( new Action( () => {
                    if ( control.IsDisposed ) {
                        return;
                    }
                    control.Visible = value;
                    control.Enabled = value;
                    control.Refresh();
                } ) );
            }
            else {
                control.Visible = value;
                control.Enabled = value;
                control.Refresh();
            }
        }

C#: Safely set the Maximum of the ProgressBar across threads.


        /// <summary>
        ///     Safely set the <see cref="ProgressBar.Maximum"/> of the ProgressBar across threads.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="value"></param>
        public static void Maximum( this ProgressBar control, int value ) {
            if ( null == control ) {
                return;
            }
            if ( control.InvokeRequired ) {
                control.BeginInvoke( new Action( () => {
                    if ( control.IsDisposed ) {
                        return;
                    }
                    control.Maximum = value;
                    control.Refresh();
                } ) );
            }
            else {
                control.Maximum = value;
                control.Refresh();
            }
        }

C#: Safely set the Visible of a Control across threads.


        /// <summary>
        ///     Safely set the <see cref="Control.Visible"/> of the control across threads.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="value"></param>
        public static void Visible( this Control control, Boolean value ) {
            if ( null == control ) {
                return;
            }
            if ( control.InvokeRequired ) {
                control.BeginInvoke( new Action( () => {
                    if ( control.IsDisposed ) {
                        return;
                    }
                    control.Visible = value;
                    control.Refresh();
                } ) );
            }
            else {
                control.Visible = value;
                control.Refresh();
            }
        }

C#: Safely set the Enabled of the Control across threads.


        /// <summary>
        ///     Safely set the <see cref="Control.Enabled"/> of the control across threads.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="value"></param>
        public static void Enabled( this Control control, Boolean value ) {
            if ( null == control ) {
                return;
            }
            if ( control.InvokeRequired ) {
                control.BeginInvoke( new Action( () => {
                    if ( control.IsDisposed ) {
                        return;
                    }
                    control.Enabled = value;
                    control.Refresh();
                } ) );
            }
            else {
                control.Enabled = value;
                control.Refresh();
            }
        }

C#: Safely set the Checked of the CheckBox across threads.


        /// <summary>
        ///     Safely set the <see cref="CheckBox.Checked"/> of the CheckBox across threads.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="value"></param>
        public static void Checked( this CheckBox control, Boolean value ) {
            if ( null == control ) {
                return;
            }
            if ( control.InvokeRequired ) {
                control.BeginInvoke( new Action( () => {
                    control.Checked = value;
                    control.Refresh();
                } ) );
            }
            else {
                control.Checked = value;
                control.Refresh();
            }
        }

C#: Safely set the Text of a ToolStripItem across threads.


        /// <summary>
        ///     Safely set the <see cref="ToolStripItem.Text"/> of the ToolStripItem across threads.
        /// </summary>
        /// <param name="toolStripItem"></param>
        /// <param name="value"></param>
        public static void Text( this ToolStripItem toolStripItem, String value ) {
            if ( null == toolStripItem ) {
                return;
            }
            if ( toolStripItem.IsDisposed ) {
                return;
            }
 
            toolStripItem.OnThread( () => {
                if ( toolStripItem.IsDisposed ) {
                    return;
                }
                toolStripItem.Text = value;
                toolStripItem.Invalidate();
            } );
        }

C#: Safely set the Text of a Control across threads.


        /// <summary>
        ///     Safely set the <see cref="Control.Text"/> of a control across threads.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="value"></param>
        public static void Text( this Control control, String value ) {
            if ( null == control ) {
                return;
            }
            if ( control.InvokeRequired ) {
                control.BeginInvoke( new Action( () => {
                    if ( control.IsDisposed ) {
                        return;
                    }
                    control.Text = value;
                    control.Refresh();
                } ) );
            }
            else {
                control.Text = value;
                control.Refresh();
            }
        }

C#: Safely get the Text of a Control across threads.


        /// <summary>
        ///     Safely get the <see cref="Control.Text"/> of a <see cref="Control"/> across threads.
        /// </summary>
        /// <remarks>
        ///     http://kristofverbiest.blogspot.com/2007/02/don-confuse-controlbegininvoke-with.html
        /// </remarks>
        /// <param name="control"></param>
        /// <returns></returns>
        public static String TextGet( this Control control ) {
            if ( null == control ) {
                return String.Empty;
            }
            return control.InvokeRequired ? control.Invoke( new Func<string>( () => control.Text ) ) as String : control.Text;
        }

C#: Perform an Action on a ToolStripItem's thread.


        /// <summary>
        /// Perform an <see cref="Action"/> on a <see cref="ToolStripItem"/>'s thread.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="action"></param>
        public static void OnThread( this ToolStripItem control, Action action ) {
            if ( null == control ) {
                return;
            }
            if ( null == action ) {
                return;
            }
            var parent = control.GetCurrentParent() as Control;
            if ( null != parent ) {
                parent.OnThread( action );
            }
        }

C#: Perform an Action on the Control's thread.


        /// <summary>
        /// Perform an <see cref="Action"/> on the control's thread.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="action"></param>
        public static void OnThread( this Control control, Action action ) {
            if ( null == control ) {
                return;
            }
            if ( null == action ) {
                return;
            }
            if ( control.InvokeRequired ) {
                control.BeginInvoke( action );
                control.Invalidate();
            }
            else {
                action();
                control.Invalidate();
            }
        }