Tuesday, September 29, 2009

Thread-safe general delegate invoke method

When dealing with events and delegates in a UI with worker threads you have to check if check if invocation is required in the eventhandler.
Instead of doing the test in all eventhandlers I made a general Invoke method to handle this.
When invocation is not required this method is slower, but when invocation is required it´s faster.
The thing for me is that if I always use this method I don´t have to worry about dealing with this in every eventhandler or when raising events.

public static class ThreadUtility
{
 public static void Invoke(Delegate source, params object[] args)
 {
  if (source == null) return;
  int paramCount = source.Method.GetParameters().Length;
  if (paramCount != args.Length) throw (new ArgumentException(string.Format("Invalid number of parameters. {0} was expected, {1} was supplied", paramCount, args.Length)));
  foreach (Delegate invocationItem in source.GetInvocationList())
  {
   if (IsDisposed(invocationItem.Target)) continue;
   ISynchronizeInvoke target = invocationItem.Target as ISynchronizeInvoke;
   if (target != null && target.InvokeRequired)
   {
    target.BeginInvoke(invocationItem, args);
   }
   else
   {
    invocationItem.DynamicInvoke(args);
   }
  }
 }

 private static bool IsDisposed(object target)
 {
  PropertyInfo propertyInfo = target.GetType().GetProperty("IsDisposed");
  if (propertyInfo == null) return (false);
  return ((bool)propertyInfo.GetValue(target, null));
 }
}

This is how it looks the old way...

public event EventHandler ThreadUtilTest;
public void OnThreadUtilTest()
{
 EventHandler temp = ThreadUtilTest;
 if (temp != null)
 {
  temp(this, new EventArgs());
 }
}

private void ThreadUtilTestHandler(object sender, EventArgs e)
{
 if (InvokeRequired)
 {
  Invoke(temp, sender, e);
  return;
 }
 // Execute operation
}

...and this is how it looks the with my method...

public event EventHandler ThreadUtilTest;
public void OnThreadUtilTest()
{
 ThreadUtility.Invoke(ThreadUtilTest, this, new EventArgs());
}

private void ThreadUtilTestHandler(object sender, EventArgs e)
{
 // Execute operation
}

When using events you usualy don´t want to add multiple instances of the same eventhandlers for the same object.
Here´s a way to avoid that...

private object _eventSychLock = new object();
private EventHandler _event;
public event EventHandler ThreadUtilTest
{
 add
 {
  lock (_eventSychLock)
  {
   if (!ThreadUtility.InInvocationList(_event, value))
   {
    _event += value;
   }
  }
 }
 remove
 {
  lock (_eventSychLock)
  {
   _event -= value;
  }
 }
}

public void OnThreadUtilTest()
{
 ThreadUtility.Invoke(_event, this, new EventArgs());
}

public static class ThreadUtility
{
 public static bool InInvocationList(Delegate source, Delegate subscriber)
 {
  if (source == null) return (false);
  if (subscriber == null) return (true);
  foreach (Delegate invocationItem in source.GetInvocationList())
  {
   if (invocationItem == subscriber) return (true);
  }
  return (false);
 }
}

Monday, June 22, 2009

How to use comments wisely

How can comments be a security issue?

  1. If you have to use comments to explain your code, the code is probably too complicated. When creating a complicated solution to solve a problem you insert errors, bugs or just making it har to maintain.
  2. A comment that doesn´t describe the code correctly may lead readers of the code to think it does something it doesn´t, making it harder to maintain.
  3. Comments gets stale, when you change/refactor your code you´ll forget to change your comments. Se #2.
  4. It may be hard to correctly describe what the code does in plain text. Se #2.

Code should be written in a way to make comments redundant.
For example give methods, variables and fields names to describe what they do or what they are representing is a good start.

Use comments to document how to use classes and methods, for other programmers using them to know how to. Be sure to update the documentation as you change/refactor the code.

Finally a quote I really like:
"When I have a specific goal in mind and a complicated piece of code to write, I spend my time making it happen rather than telling myself stories about it." - Steve Yegge

Thursday, June 11, 2009

To TryParse or not, is it a question?

Use TryParse when converting a string to a ValueType.

Why?
There´s really no reason not to, it is:
- faster.
- safer, you will not have to be bothered with exceptions.
- easy, for all but DateTime.
and it will always work, unless you want an exception to be propagated.

Using Xxx.Parse or Convert.ToXxx will throw an exception if the string is not valid for conversion.
You may think that when an invalid value is rare the Xxx.Parse or Convert.ToXxx is not gonna throw an exception and it will be faster for most cases.

If you do, my opinion is you´re wrong.
Throwing exceptions when you can avoid it is bad practice and (cpu)time consuming.
Making it a habit to ignore this sort of basic rules is going to lead to other bad decisions when writing code.

I have tried it my self but I have no data to support it.
Others have, look at the result they´ve made:

Parsing Performance @stackoverflow
TryParse and the Exception Tax @codinghorror
int.Parse for Integer Conversion in C# @dotnetperls


Examples
public static Int32 ToInt32(string text)
{
   Int32 result;
   if (Int32.TryParse(text, out result))
   {
       return (result);
   }
   return (0);
}
The only reason to convert to a data type from string and depending on try-catch is if you are using a method with a generic data type as input and you know that invalid values is rare.
public static T ConvertToType<T>(string text)
{
   try
   {
       if (string.IsNullOrEmpty(text))
       {
           return (default(T));
       }
       return (T)Convert.ChangeType(text, typeof(T), CultureInfo.CurrentUICulture);
   }
   catch
   {
       return (default(T));
   }
}
Or a general method for conversion of string to an unknown(at design time) datatype:
public static object ConvertToType(string text, Type type)
{
   object defaultValue = GetDefault(type);
   try
   {
       if (string.IsNullOrEmpty(text))
       {
           return (defaultValue);
       }
       return (Convert.ChangeType(text, type, CultureInfo.CurrentUICulture));
   }
   catch
   {
       return (defaultValue);
   }
}


Conclusion
Use TryParse if you don´t want an exception to propagate or you want to use a generic method and you know that an invalid value is rare.

Tuesday, June 9, 2009

Recomended software security books

CLR via C# by Jeffrey Richter

A good book with a lot of samples and recommendations regarding C# code and how CLR realizes it.

19 Deadly Sins of Software Security by Michael Howard, David LeBlanc, John Viega

Descriptions and solutions of how to eliminate these 19 security flaws from your code.

Software Security: Building Security In by Gary McGraw

Describing the development process from The Security Development Lifecycle(SDL) point of view.