Electronics DIY blog

DIY is fun and is food for the brain and spirit. Don't be afraid to learn.



Thursday, February 7, 2013

C# Tracing code

Tracing code is a nice way to check your app behaviour when you are running it in a machine without the comfort of your compiler/debugger.
If you have doubts about a region of your code or you want to output information from you app you can simply output Trace messages to check what's going on.

Trace can be done to a file, a control, or any text recipient via a TraceListener based class.

Following my previous articles (1, 2) on C# extensions the following extension is a nice, handy peace of software to keep in your apps or reusable libraries to perform Trace output to any TextBoxBase derived class (ex. TextBox, RichTextBox, etc...).

Did you read my article on cross thread calls? This will make use of that tool to perform in a clean easy way extend the TextBoxBase.AppendText with/without auto scroll in a thread-safe/non thread-safe context. Take a look at this.

namespace Extensions
{
    public static class TextBoxBaseExtensions
    {
        /// <summary>
        /// Appends text to TextBoxBase Control and auto-scrolls to end
        /// </summary>
        /// <param name="tbb">TextBoxBase object</param>
        /// <param name="text">Text to append</param>
        static public void AppendTextAndScroll(this TextBoxBase tbb, string text)
        {
            tbb.AppendText(text);
            tbb.SelectionStart = tbb.Text.Length;
            tbb.ScrollToCaret();
        }

        /// <summary>
        /// Appends text to TextBoxBase Control in a UI Thread safe manner
        /// </summary>
        /// <param name="tbb">TextBoxBase object</param>
        /// <param name="text">Text to append</param>
        public static void SafeAppendText(this TextBoxBase tbb, string text)
        {
            tbb.SafeInvoke(delegate
            {
                tbb.AppendText(text);
            });
        }

        /// <summary>
        /// Appends text to TextBoxBase Control and auto-scrolls to end in a UI Thread safe manner
        /// </summary>
        /// <param name="tbb">TextBoxBase object</param>
        /// <param name="text">Text to append</param>
        public static void SafeAppendTextAndScroll(this TextBoxBase tbb, string text)
        {
            tbb.SafeInvoke(delegate
            {
                tbb.AppendTextAndScroll(text);
            });
        }
    }
}

Sweet.
You can now call on any TextBoxBase derived class any of the above methods.
To make use of this to perform trace listening you can simply do this:

using Extensions
/// <summary>
/// Defines a TextBoxBase Control TraceListener.
/// </summary>
public class TextBoxBaseTraceListener : TraceListener
{
    /// <summary>
    /// Gets or sets the TraceListener Control 
    /// </summary>
    public TextBoxBase Control
    {
        get;
        set;
    }

    /// <summary>
    /// Initializes the TextBoxBaseTraceListener object.
    /// </summary>
    /// <param name="control">The target TextBoxBase control.</param>
    public TextBoxBaseTraceListener(TextBoxBase control)
    {
        this.Control = control as TextBoxBase;
        if (this.Control == null)
        {
            throw new ArgumentException("The argument is not a TextBoxBase control", "control");
        }
    }

    /// <summary>
    /// Captures and display a Trace.Write call.
    /// </summary>
    /// <param name="message">The trace text message.</param>
    public override void Write(string message)
    {
        this.Control.SafeAppendTextAndScroll(message);
    }

    /// <summary>
    /// Captures and display a Trace.WriteLine call. Add NewLine char sequence to the end of the string.
    /// </summary>
    /// <param name="message">The trace text message.</param>
    public override void WriteLine(string message)
    {
        this.Control.SafeAppendTextAndScroll(message + System.Environment.NewLine);
    }
}

And use it like any other trace listener:

TextBoxBaseTraceListener myTracer = new TextBoxBaseTraceListener(richtextBox1); // the target control goes here
Trace.Listeners.Add(myTracer);

With these to lines you now intercept any Trace.Write Trace.WriteLine calls and show the message content.

Easy as pie.

C# Getting around Illegal Thread Safe Calls

Every time you try to mess with a control from a thread other than the owner-thread you will get the IllegalCrossThreadCall exception and your app will crash.

The lazy/dangerous way to get around this is to set the Control.CheckForIllegalCrossThreadCalls on the owner/parent control to false.

If your absolutely sure of what you're doing it's ok. But still not advisable.

The right way is to perform a check on the InvokeRequired property of the control and if so Invoke/BeginInvoke (synchronously or asynchronously it's up to you) the method via a delegate.
This is fine but if you have to expand this along your code it gets kind of boring.

If you read my previous article I've talked about a cool .NET feature called Extension Methods.

What I'll show you next is a very handy peace of code that you can put in a library and reuse in any app you do.

using System;
using System.Windows.Forms;

namespace Extensions
{
    public delegate void UIDelegate();

    /// <summary>
    /// Control class extension methods
    /// </summary>
    static public class ControlExtensions
    {
        /// <summary>
        /// Performs a UI Thread safe Control.Invoke.
        /// </summary>
        /// <param name="control">Target control.</param>
        /// <param name="dlg">delegate method to be invoked.</param>
        static public void SafeInvoke(this Control control, UIDelegate dlg)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(dlg);
                return;
            }

            dlg.Invoke();
        }

        /// <summary>
        /// Performs a UI Thread safe Control.BeginInvoke.
        /// </summary>
        /// <param name="control"></param>
        /// <param name="dlg">delegate method to be invoked asynchronously.</param>
        static public void BeginSafeInvoke(this Control control, UIDelegate dlg)
        {
            if (control.InvokeRequired)
            {
                control.BeginInvoke(dlg);
                return;
            }

            dlg.Invoke(null, null);
        }
    }
}

Basically I've extended the Control type class and "added" 2 new methods.

To perform a thread safe operation inside, for example a form, we only have to add our Extensions namespace and call the code like this.

this.SafeInvoke(delegate
{
    /// do stuff...
});

That's it. It's a pretty clean away of performing operations over controls in a thread safe manner.

;-)

Wednesday, February 6, 2013

C# Extension Methods

Extension methods is a good way of "adding" extra functionalities to a type without having to create a new type of class by inheritance.
This is very useful if your trying to:

  • Extend a class/type for which you don't hold the source
  • Extend a class/type without the need to create a derived type
  • Extend a sealed class/type

Here is a small example:
Ever tried to call the .ToString() method on an object that is null?
Guess what happens?
Yes. You get an exception! Your program explodes! GHAAAA!
Who to fix this?
Test if object is anything else but null. But you have to do this in every peace of code you want to convert type to string.
You could do a method that takes an argument and returns a string.

But there are cleaner/smarter ways to do this.
This is where extension methods kicks in.

Take a look at this class.

/// <summary>
/// object Extention methods
/// </summary>
public static class ObjectExtensions
{
     /// <summary>
     /// Extends the ToString Method for object types. Adds null objects support.
     /// </summary>
     /// <param name="obj">The object variable</param>
     /// <returns>String conversion of the object. Supports null objects</returns>
     public static string ToStringEx(this object obj)
     {
         return (obj == null) ? string.Empty : obj.ToString();
     }
}

The static method inside this also static class takes an argument that is the object it self (that's why the this word is before the argument).
What this actually does is to extend the object type. object type is the origin point of all classes in C# so everything derives from object.
By extending the object type like in the code above you will be able to call .ToString() or .ToStringEx() on every type.

For example lets say you have a class named Foo and you declare an object of that type.

Foo a;
a.ToStringEx(); // Will return an empty string
a.ToString(); // Will throw an exception because a is not an instance of an object

If your extension needs some input arguments it's as simple as:

public static returntype MyMethod(this targettype obj, type arg1, type arg2, ...)


There are some limitations
  • Your extensions can only come in the form of methods (forget about extending properties, events, etc...)
  • Your extension can only create new objects inside it's scope. No new object inside the class are allowed. For that you must inherit/derive a new class

For more info check out MSDN

New course for the blog

Since I broke my CNC the blog evolution has been quite "dead".
I'm waiting to get access to some nice tools to repair my CNC. Till then I've decided to widen the spectrum of this blog and talk a little about one of my other areas. Coding. I do alot of coding in my job and at home so along the years I've been getting some skill in a couple of laguages (C-like ones mostly but also VB, Java, some ASM, and others).

To keep this blog more "lively" I've decided to throw a couple of articles about coding. Mainly C# my all time favourite high end language.

So here it goes...