Aug 12

I made a very basic solution for those who have trouble to get NHibernate up and running with unit tests.

  • Configuration is done via xml.
  • LinFu is used as proxy factory.
  • MbUnit / Galio is used for testing, dlls are included.
  • NHibernate 2.1 and all the required files are included.
  • SQLite is included for both, 32bit 64bit.

For those who have a 64bit os, as long as you use the ReSharpers test runner, everything should work fine. If you want to use another test runner, Icarus for example, you’d have to reference System.Data.SQLite.DLL from lib/sqlite64.

If there is anything wrong, please leave a comment.

The archive is available here.

Tagged with:
Jul 08

If you know how much pain it is to debug / unit test multi threaded code, you likely don’t want to do it again.

The biggest problem is that you can’t be sure if it would work if it was single threaded, so that there are solely bugs introduced by concurrently accesses.

You could of cause alter all affected parts by hand to run on a single thread, just to verify that there are indeed no other logic bugs. But as it would be time consuming and sometimes not practical at all as there is just too much involved, you shouldn’t do that.

Therefore I’d advice you to use a single point where you deal with all threading stuff, some kind of action executor.

A interface could look like this:

public interface IActionExecutor
{
    void Execute(Action action, Action callBack, Action<Exception> errorHandle);
    void Execute(Action action, Action callBack);
    void Execute(Action action, Action callBack, bool executeCallBackInMainThread);
    void Execute(Action action);
    void Execute(Action action, bool executeInMainThread);
}

For production purpose, the multi threaded implementation could be as simple as this:

public class MultiThreadedActionExecutor : IActionExecutor
{
    #region IActionExecutor Members

    public void Execute(Action action, Action callBack, Action<Exception> errorHandle)
    {
        new Thread(() =>
                       {
                           try
                           {
                               action();
                               SyncContext.Current.Post(x =< callBack(), null);
                           }
                           catch (Exception ex)
                           {
                               errorHandle(ex);
                           }
                       }).Start();
    }

    public void Execute(Action action, Action callBack)
    {
        Execute(action, callBack, false);

    }

    public void Execute(Action action)
    {
        Execute(action, false);
    }

    public void Execute(Action action, Action callBack, bool executeCallBackInMainThread)
    {
        new Thread(() =<
        {
            try
            {
                action();
                if (executeCallBackInMainThread)
                {
                    SyncContext.Current.Post(x =< callBack(), null);
                }
                else
                {
                    callBack();
                }

            }
            catch(Exception)
            {
#if DEBUG
                throw;
#endif
            }
        }).Start();
    }

    public void Execute(Action action, bool executeInMainThread)
    {
        new Thread(() =<
                       {
                           try
                           {
                               if (executeInMainThread)
                               {
                                   SyncContext.Current.Post(x =< action(), null);
                               }
                               else
                               {
                                   action();
                               }
                           }
                           catch (Exception)
                           {
#if DEBUG
                               throw;
#endif
                           }
                       }).Start();
    }

    #endregion
}

The SyncContext just contains the SynchronizationContext of the main thread, this is my implementation:

public class SyncContext
{
    private static SynchronizationContext _current;

    public static SynchronizationContext Current
    {
        get { return _current; }
    }

    public static void Initialize()
    {
        if (_current == null)
        {
            _current = SynchronizationContext.Current;
        }
    }
}

And for unit testing or debugging, you can use this single threaded implementation

public class SingleThreadedActionExecutor
{
    public void Execute(Action action, Action callBack, Action<Exception> errorHandle)
    {
        try
        {
            action();
            callBack();
        }
        catch (Exception ex)
        {
            errorHandle(ex);
        }
    }

    public void Execute(Action action, Action callBack)
    {
        Execute(action, callBack, false);
    }

    public void Execute(Action action)
    {
        Execute(action, false);
    }

    public void Execute(Action action, Action callBack, bool executeCallBackInMainThread)
    {
        try
        {
            action();

            callBack();
        }

        catch (Exception)
        {
#if DEBUG
            throw;
#endif
        }
    }

    public void Execute(Action action, bool executeInMainThread)
    {
        try
        {
            action();
        }
        catch (Exception)
        {
#if DEBUG
            throw;
#endif
        }
    }
}

Although you should use a dependency injection tool like StructureMap, you could also use a static variable exposing the current IActionExecuter, in both cases you would only have to change one line of code to turn all multi threaded actions to single threaded ones and vice versa.

Another benefit would be, you don’t have to do the tedious invoking when working with WindowsForms. If you are using the MVP pattern, this will be a great time saver.

Tagged with:
preload preload preload