Jul272009

Type-safe INotifyPropertyChanged and derived classes

Published by eric at 7:50 AM under .NET Framework | C# | Windows | WPF

Some of you who read my previous blog post notice that this technique doesn't allow to raise “PropertyChanged” event from a derived class. This is because you can only call method of “PropertyChangedEventHandler” from the class where it is defined. Anywhere else you can only assign (+=) and unassign (-=) event handler.

One way to work around this is to add a method in your base model class that will forward the call to “PropertyChangedEventHandler”.

Here is a modified copy of the class from my previous post:

public class Model : INotifyPropertyChanged
{
    private string _data;

    public string Data
    {
        get { return _data; }
        set
        {
            if (_data == value)
                return;

            _data = value;

            // Type safe raise from base method
            RaisePropertyChanged(() => Data);
        }
    }

    protected void RaisePropertyChanged(Expression<Func<object>> expression)
    {
        PropertyChanged.Raise(expression);   
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged = null;

    #endregion
}

Now you can define a derived class and use the same method to raise a PropertyChanged event.

public class DerivedModel : Model
{
    private string _moreData;

    public string MoreData
    {
        get { return _moreData; }
        set
        {
            if (_moreData == value)
                return;

            _moreData = value;
            RaisePropertyChanged(() => MoreData);
        }
    }
}

Now with very little effort you can build a type-safe and bindable data model.

It is also useful to be able to raise many property at once. For example if have calculated properties that depends on others like in this sample class:

public class User : INotifyPropertyChanged
{
    private string _lastName;

    public string LastName
    {
        get { return _lastName; }
        set
        {
            if (_lastName == value)
                return;

            _lastName = value;
            RaisePropertyChanged(()=>LastName, ()=>FullName);
        }
    }

    private string _firstName;

    public string FirstName
    {
        get { return _firstName; }
        set
        {
            if (_firstName == value)
                return;

            _firstName = value;
            RaisePropertyChanged(() => FirstName, () => FullName);
        }
    }

    public string FullName
    {
        get { return String.Format("{0} {1}", _firstName, _lastName); }
    }

    public void RaisePropertyChanged(params Expression<Func<object>>[] expression)
    {
        PropertyChanged.Raise(expression);
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged = null;

    #endregion
}

Because a change to either “FirstName” or “LastName” should trigger a change to “FullName” you have to raise both changes from both properties. Of course you can call “RaisePropertyChanged” many times but with a simple overload you can do this. All you have to do is add this to your extensions class.

public static void Raise(this PropertyChangedEventHandler handler, params Expression<Func<object>>[] proppertyExpressions)
{
    foreach (var expression in proppertyExpressions)
        Raise(handler, expression);
}

Aside from beeing type safe, this method will give you intellisense support while you type your “RaiePropertyChanged” calls. You still have to type the right property though.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 2 Responses

Jul222009

How to use INotifyPropertyChanged, the type-safe way (no magic string)

Published by eric at 10:43 PM under .NET Framework | C# | Windows | WPF

Implementation of the INotifyPropertyChanged interface is quite simple. There is only one event to implement. Take for example the following simple model class:

public class Model : INotifyPropertyChanged
{
    private string _data;

    public string Data
    {
        get { return _data; }
        set
        {
            if (_data == value)
                return;

            _data = value;

            // Type un-safe PropertyChanged raise 
            PropertyChanged(this, new PropertyChangedEventArgs("Data"));
        }
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged = null;

    #endregion
}

This is a pretty standard way to implement a bindable property. The problem here is the “Data” string to specify which property changed. If someone change the name of the property without changing the content of the string, the code will compile fine but won’t work. In a big application with may properties it can be hard to detect and find the problem.

The best solution is to rely on the compiler to warn us. But because the property name is a string it can’t. So let’s change that line with a type-safe one.

public class Model : INotifyPropertyChanged
{
    private string _data;

    public string Data
    {
        get { return _data; }
        set
        {
            if (_data == value)
                return;

            _data = value;

            // Type safe PropertyChanged raise
            PropertyChanged.Raise(() => Data);
        }
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged = null;

    #endregion
}

What is the trick? Raise is an extension method that takes a lambda expression to specify the name of the property in a type safe way. The Raise method resolve this expression to extract the name of the property and pass it to the PropertyChanged event.

public static class PropertyChangedExtensions
{
    public static void Raise(this PropertyChangedEventHandler handler, Expression<Func<object>> propertyExpression)
    {
        if (handler != null)
        {
            // Retreive lambda body
            var body = propertyExpression.Body as MemberExpression;
            if (body == null)
                throw new ArgumentException("'propertyExpression' should be a member expression");

            // Extract the right part (after "=>")
            var vmExpression = body.Expression as ConstantExpression;
            if (vmExpression == null)
                throw new ArgumentException("'propertyExpression' body should be a constant expression");

            // Create a reference to the calling object to pass it as the sender
            LambdaExpression vmlambda = Expression.Lambda(vmExpression);
            Delegate vmFunc = vmlambda.Compile();
            object vm = vmFunc.DynamicInvoke();

            // Extract the name of the property to raise a change on
            string propertyName = body.Member.Name;
            var e = new PropertyChangedEventArgs(propertyName);
            handler(vm, e);
        }
    }
}

All you have to do is to put this extension method in your code and the jib is done. Of course at the end a string will be used to raise the PropertyChanged event but because you don’t have to type it, you don’t have to maintain it.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses

Jun262009

Modifying the Commerce Server 2009 Contemporary site’s site definition (Part 1)

Published by david at 10:54 AM under SharePoint 2007 | Commerce Server

While building a new site with Commerce Server 2009 SharePoint services, we wanted to redesign the site and modify a lot of pages. The problem is that for us to do that 3 solutions were possible per Microsoft’s documentation:

  1. Use the extensibility kit to edit the pages and master pages
  2. Change the necessary pages directly in the Layouts folder of that SharePoint hive
  3. Modify the pages in SharePoint designer

None of these solutions were suitable for our need and here are the reasons:

  1. I do not recommend using the extensibility kit because we need to re-sign all the assemblies with a new key and change all references to the public key token. Also, if you modify the extensibility kit, you are making it very difficult to upgrade to future versions of CS 09, unless you only add web parts or pages. Finally, the extensibility kit does not include the contemporary site, which is the one we want to keep as a basis.
  2. Changing the pages in the layouts folder is not a good idea because you basically change it for all of your sites. Of course it’s not an issue because usually there is only one CS site per machine. but still it can be an issue in a dev machine or if ever CS 09 should be used as Saas (Software as a service). Finally, this solution is not re-deployable.
  3. Modifying the pages in SharePoint is also a plausible solution but again it is not deployable and it breaks the site definition.

So, what is the solution? It is to repackage the Contemporary site SharePoint solution and adding your custom features and modified pages. The following modifications were done in MOSS and not in WSS. I’m sure it is possible in WSS though. Also, for the packaging in wsp, I’m using WspBuilder.

So, here we go:

1. Un-pack the MicrosoftCommerceMOSSDefaultSiteV2.WSP file to any folder, let’s say “C:\ContemporarySite”. Your contents should look like this:

image 

2. Now you need to restructure the features and files for WspBuilder. So essentially you would have:

Copy the following folders in 12\Templates\Features:

CommerceServerContemporarySiteCheckOutStepsInstance CommerceServerContemporarySiteImages CommerceServerContemporarySiteProvisioner CommerceServerContemporarySiteResourceDeployment CommerceServerContemporarySiteResources CommerceServerContemporarySiteSPListSampleData CommerceServerContemporarySiteXslts CommerceServerMyAccountSiteMapProvider

Copy the following folders in 12\Templates:

1033
CONTROLTEMPLATES
IMAGES
LAYOUTS
SiteTemplates

Copy the following folder in 12:
Resources
Copy the following files in the GAC folder:

Microsoft.Commerce.Portal.ContemporarySite.dll
Microsoft.Commerce.Portal.ContemporarySiteCommon.dll

 

Now that the basic structure is done, you are able to re-create the Contemporary site’s WSP solution and deploy it using Commerce Server SharePoint Services configurations tool. Before that though you will need to modify the SharePointCommerceServicesConfiguration.exe.config to take the new WSP file:

<sharePointSolutionGroup name="DefaultSiteAndWebPartsMoss" sharePointPlatform="moss" defaultInSilentMode="True">
            <sharePointSolutions>
                <sharePointSolution id="7b93b2ca-e1e4-4783-a038-14094933c002" file="MicrosoftCommerceWebParts.wsp" version="1.0.0.0" wspKey="1"/>
                <sharePointSolution id="Your solution ID Here" file="Your Solution Name Here.wsp" version="1.0.0.0" wspKey="2"/>
            </sharePointSolutions>
            <defaultWebApplicationSettings name="SharePoint - 8088" port="8088" extendedName="SharePoint - 8089" extendedPort="8089" appPoolId="SharePoint - Pool 8088" appPoolUser="domain\someone"/>
            <defaultSiteCollectionSettings create="True" title="Home" name="ContemporarySite" admin="domain\someone" template="MOSSCSContemporarySite"/>
            <defaultCommerceServerSiteSettings create="True" name="ContemporarySite" description="Commerce Server Site for Commerce SharePoint Contemporary Web Site" siteWithSampleData="False" databaseServer="."/>
</sharePointSolutionGroup>

 

Now you can use the configuration tool to deploy your site. Please be advised though that your MOSS environement needs to be clean because you are essentially redeploying the same feature as the contemporary site. Also, do not modify the name of the Contemporary Site’s site definition configuration names such as “MOSSCSContemporarySite” because the receivers look for those configurations.

In the next part of my post, I’ll show you how to modify the master pages and add new features to your site.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 3 Responses

Jun262009

SharePoint Tool Basket

Published by eric at 7:51 AM under SharePoint 2007

Belgian MVP Releases SharePoint Tool Basket on CodePlex!

Picture of SharePoint Tool Basket

MVP Stéphane Eyskens recently produced a new SharePoint project on Codeplex called “SharePoint Tool Basket”. Within two months of launch, the project has appeared in the Top 10 list of the most popular Codeplex Sharepoint projects; the tool basket is proving very popular with the SharePoint community and has already been downloaded over 5,000 times!

This project aims to re-group a number of different SharePoint tools into one single container. The tool basket offers features such as SharePoint Document Rating, Form Designer, Ajax-enabled lookup field, Content Type Explorer, Feature Explorer and Audience to Group convertor.

If you have an interest in Microsoft SharePoint, the Tool Basket is well worth investigating.

Learn more about the project and download the project bits here.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags:

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses

Jun162009

My baby steps to PostSharp 1.0

Published by maxime at 1:11 PM under

So… you downloaded PostSharp 1.0 and you installed it and are wondering… “What’s next?”.

Well my friends, let me walk you through the first steps of PostSharp. What could we do that would be simple enough? Hummm… what about writing to a debug window? That sounds simple enough! Let’s start. So I created a new Console Application project and I added the reference to PostSharp.Laos and PostSharp.Public. As a requirement, the class must be tagged with “Serializable” attribute and implement OnMethodBoundaryAspect (not in all case but let’s start small here).

Next, I have a few methods I can override. The two that we are interested in right now is “OnEnter” and “OnExit”. Inside of it, we’ll say which method we are entering and which one we are exiting. Here are my Guinea pig classes:

public class FooBar
{
    [DebugTracer]
    public void DoFoo()
    {
        Debug.WriteLine("Doing Foo");
    }

    [DebugTracer]
    public void DoBar()
    {
        Debug.WriteLine("Doing Bar");
    } 
}

[Serializable]
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
public class DebugTracer : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionEventArgs eventArgs)
    {
        Debug.WriteLine(string.Format("Entering {0}", eventArgs.Method.Name));
    }

    public override void OnExit(MethodExecutionEventArgs eventArgs)
    {
        Debug.WriteLine(string.Format("Exiting {0}", eventArgs.Method.Name));
    }
}

See how simple this is? But… does it work? Let’s see the trace of calling each methods:

Entering DoFoo
Doing Foo
Exiting DoFoo
Entering DoBar
Doing Bar
Exiting DoBar

Isn’t that wonderful? Compile execute and enjoy. But… what about the community you say? Of course if the tool is not open source there is probably nothing built around it, right? Wrong!

Here is a few resources for PostSharp that include pre-made attributes that are ready to be used:

That was everything I could find. Do you know any others?



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags:

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses

Jun162009

PostSharp – The best way to do AOP in .NET

Published by maxime at 1:10 PM under

Who knows about Aspect-Oriented Programming (AOP)? Come on! Don’t be shy! Ok, now lower your hands. My prediction is that a lot of you didn’t raise their hands. So let’s resume what AOP is:

Aspect-oriented programming is a programming paradigm that increases modularity by enabling improved separation of concerns. This entails breaking down a program into distinct parts (so called concerns, cohesive areas of functionality). […]

So what does it mean truly? Well, it’s a way to declare part of your software (methods, classes, assembly) to have a “concern” applied to them. What is a concern? Logging is one. Exception handling is another one. But… let’s go wild… what about caching, impersonation, validation (null check, bound check), are all concerns. Do you mix them with your code? Right now… you are forced to do it.

The state of current AOP

Alright for those who raised their hands earlier, what are you using for your AOP concerns? If you are using patterns and practices Policy Injection module, well, you are probably not happy. First, all your objects need to be constructed by an object builder and need to inherit from MarshalByRefObject or implement an interface.

This is not the best way but it’s been done in the “proper” way without hack.

What is PostSharp bringing?

PostSharp might be a “hack” if think so. Of course, it does require you to have it installed on your machine while compiling for it to work. But… what does PostSharp does exactly? It does what every AOP should do. Inject the code before and after the matching method at compile time. Not just PostSharp methods but any methods that is inherited from the base class PostSharp is offering you. Imagine what you could do if you could tell the compiler to inject ANY code before/after your method on ANY code you compile. Think of the possibilities. I’ll give you 2 minutes for all this information to sink in… (waiting)… got it? Start to see the possibility? All you need to do is put attributes on your methods/attributes like this:

[NotNullOrEmpty]
public string Name { get; set; }

[Minimum(0)]
public int Age { get; set; }

Now look at that code and ask yourself what it do exactly. Shouldn’t be hard. The properties won’t allow any number under “0” to be inserted inside “Age” and “Name” will not allow any null or empty string. If there is any code that try to do that, it will throw a ValidationException.

Wanna try it?

Go download PostSharp immediatly and it’s little friend ValidationAspects on Codeplex. After you have tried, try to build your own and start cleaning your code to achieve better readability.

And yes… both are Open-Source and can be used at no fee anywhere in your company.

Suggestion to CLR Team

Now, PostSharp force us to have it installed with the MSI for it to work because it needs to install a Post-Compile code injector (like some obfuscation tools). What would be really nice, is to be able to do the same thing built-in with the compiler. The compiler is already checking for some attribute already… I would love to have this “internal working” exposed to the public so that we can build better tools and, more importantly, better code.

UPDATE: I want to mention that PostSharp is NOT open-source. However is free unless you need to package it with your tool.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags:

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses

Jun022009

How to implement “lock” with timeout?

Published by eric at 9:57 PM under C#

Anybody who did any multithreaded application probably used the “lock” keyword. This is actually a good thing.

“lock” is the most optimized way to lock a resource. First let’s take a look at what lock really do. Here is the simple Account class we will use for this post.

using System.Threading;

namespace Banking
{
    public class Account
    {
        private readonly string _accountNumber;
        private double _balance;

        private Account(string accountNumber, double amount)
        {
            _accountNumber = accountNumber;
            Balance = amount;
        }

        public string AccountNumber
        {
            get { return _accountNumber; }
        }

        public double Balance
        {
            get { return _balance; }
            set { _balance = value; }
        }

        public static Account OpenNew(string accountNumber, double amount)
        {
            return new Account(accountNumber, amount);
        }

        public void Deposit(double amount)
        {
            Interlocked.Exchange(ref _balance, _balance + amount);
        }

        public void Withdraw(double amount)
        {
            Interlocked.Exchange(ref _balance, _balance - amount);
        }

        public static void Transfer(double amount, Account fromAccount, Account toAccount)
        {
            // Bad code here. Potential deadlock.
            lock (fromAccount)
            lock (toAccount)
            {
                fromAccount.Withdraw(amount);
                toAccount.Deposit(amount);
            }
        }

        public override string ToString()
        {
            return string.Format("{0} (Balance = {1})", _accountNumber, _balance);
        }
    }
}

Here are some important things to point out about this class:

  • The constructor is private to limit the creators of this class.
  • The public OpenNew method is the only way to create an instance. This ensure that every Account starts with a name and a balance.
  • Deposit and Withdraw methods are thread safe. They both uses Interlocked class which is has low level methods to modify values.
  • Transfer is not thread safe even though it uses locks. There is a potential deadlock if two thread transfer funds using the same accounts at the same time.

Most of the time the transfer method will work without any problem but the is a slight chance of deadlock. Of course this is a fairly simple method and in fact we can use another private object field to lock on like in this sample.

private static object _syncLock = new object();

public static void Transfer(double amount, Account fromAccount, Account toAccount)
{
    // Bad code here. Potential deadlock.
    lock (_syncLock)
    {
        fromAccount.Withdraw(amount);
        toAccount.Deposit(amount);
    }
}

That mean you will need to use that _syncLock object all the time to be consistent, even if you need to lock only one of the two accounts. And because Transfer is a static method we need to make the _syncLock object static too. That mean that any other call to Transfer will have to wait until this call finish. That is a huge performance issue.

What we really need is to be able to lock actual Account objects and recover from any deadlock. The best way to do this is to use timeouts on the locking process. The caller can catch timeouts and handle it properly instead of waiting forever. Here is a better Transfer method.

public static void Transfer(double amount, Account fromAccount, Account toAccount)
{
    bool fromLock = Monitor.TryEnter(fromAccount, 1000);
    bool toLock = Monitor.TryEnter(toAccount, 1000);
    try
    {
        if (fromLock && toLock)
        {
            fromAccount.Withdraw(amount);
            toAccount.Deposit(amount);
        }
    }
    finally
    {
        if (fromLock)
            Monitor.Exit(fromLock);

        if (toLock)
            Monitor.Exit(toLock);
    }
}

This is a lot more code to write. Actually this is not far from what the lock keyword would do. Because if you look at your code with Reflector you will see that lock does translate to Monitor.Enter and Monitor.Exit (your have to look in IL not in C#). So a simple lock statement like this.

lock(obj)
{
    // do somtehing
    Console.WriteLine("Locked");
}

Would be translated to.

Monitor.Enter(obj);
try
{
    // do somtehing
    Console.WriteLine("Locked");
}
finally
{
    Monitor.Exit(obj);
}

You won’t see it in C# (with Reflector) but if you look at IL code you will see exactly the same sequence twice.

So to solve our problem, would it be nice to have something like this?

public static void Transfer(double amount, Account fromAccount, Account toAccount)
{
    Safe.Lock(new [] {fromAccount, toAccount}, 1000, () =>
    {
        fromAccount.Withdraw(amount);
        toAccount.Deposit(amount);
    });
}

This look pretty much like the well known lock keyword, isn’t it? Now how can we do this? That’s better. The Safe static call has a Lock static method that take care of everything. The fist argument can be a single object or an array of objects. This allow locking multiple object at once. The Lock method use the Monitor.TryEnter to acquire lock on objects. If this can be done before the timeout occur the Action argument is executed.

Of course this code can and should be surrounded with a try-catch block. here is how to do so.

public static void Transfer(double amount, Account fromAccount, Account toAccount)
{
    var retries = 10;

    while (retries-- > 0)
    {
        try
        {
            Safe.Lock(new[] { fromAccount, toAccount }, 1000, () =>
            {
                fromAccount.Withdraw(amount);
                toAccount.Deposit(amount);
            });
            break;
        }
        catch (TimeoutException e)
        {
            if (retries == 0)
                throw;
            Thread.Sleep(100);
        }
    }
}

In this code snippet it will retry at most 10 time to lock toAccount and fromAccount before giving up. Notice that only the TimeoutException is handled, so any other exception will be thrown immediately and stop the process. The break at the end of the try block let us out as soon as it works.

This is a good timeout pattern and easy to implement in your own code. Give it a try and let me know if it works.

Here is the full code for the Safe class.

using System;
using System.Linq;
using System.Threading;

namespace MultithreadHelper
{
    public class Safe : IDisposable
    {
        private readonly object[] _padlocks;
        private readonly bool[] _securedFlags;

        private Safe(object padlock, int milliSecondTimeout)
        {
            _padlocks = new[] {padlock};
            _securedFlags = new[] {Monitor.TryEnter(padlock, milliSecondTimeout)};
        }

        private Safe(object[] padlocks, int milliSecondTimeout)
        {
            _padlocks = padlocks;
            _securedFlags = new bool[_padlocks.Length];
            for (int i = 0; i < _padlocks.Length; i++)
                _securedFlags[i] = Monitor.TryEnter(padlocks[i], milliSecondTimeout);
        }

        public bool Secured
        {
            get { return _securedFlags.All(s => s); }
        }

        public static void Lock(object[] padlocks, int millisecondTimeout, Action codeToRun)
        {
            using (var bolt = new Safe(padlocks, millisecondTimeout))
                if (bolt.Secured)
                    codeToRun();
                else
                    throw new TimeoutException(string.Format("Safe.Lock wasn't able to acquire a lock in {0}ms",
                                                             millisecondTimeout));
        }

        public static void Lock(object padlock, int millisecondTimeout, Action codeToRun)
        {
            using (var bolt = new Safe(padlock, millisecondTimeout))
                if (bolt.Secured)
                    codeToRun();
                else
                    throw new TimeoutException(string.Format("Safe.Lock wasn't able to acquire a lock in {0}ms",
                                                             millisecondTimeout));
        }

        #region Implementation of IDisposable

        public void Dispose()
        {
            for (int i = 0; i < _securedFlags.Length; i++)
                if (_securedFlags[i])
                {
                    Monitor.Exit(_padlocks[i]);
                    _securedFlags[i] = false;
                }
        }

        #endregion
    }
}


[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags:

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses

May132009

How to test your multi-threaded code (part 3 of 3)?

Published by eric at 6:16 AM under C#

In the last post we learned how to find and fix a simple multi-thread problem. Now we will see a more complex scenario and see how CHESS wil find the solution.

To do that we will add a ne method to our Account type.

public static void Transfer(double amount, Account fromAccount, Account toAccount)
{
    lock (fromAccount)
    {
        lock(toAccount)
        {
            fromAccount.Withdraw(amount);
            toAccount.Deposit(amount);
        }
    }
}

Because we want to be sure that the transfer works we lock both the “from” and the “to” account.

Now we can easily wrtie this test to see that this is working fine in signle threaded scenario.

[TestMethod]
public void TransferTest()
{
    Account a1 = Account.OpenNew(10000);
    Account a2 = Account.OpenNew(10000);

    Account.Transfer(100, a1, a2);
    Account.Transfer(100, a2, a1);

    Assert.AreEqual(10000, a1.Balance);
    Assert.AreEqual(10000, a2.Balance);
}

As we did before we will convert this single-thread method to a multi-thread one.

[TestMethod]
[HostType("Chess")]
public void TransferMultiThreadTest()
{
    Account a1 = Account.OpenNew(10000);
    Account a2 = Account.OpenNew(10000);

    Thread thread = 
new Thread(o => Account.Transfer(100, ((Account[]) o)[0], ((Account[]) o)[1])); thread.Start(new[] {a1, a2}); Account.Transfer(100, a2, a1); thread.Join(); Assert.AreEqual(10000, a1.Balance); Assert.AreEqual(10000, a2.Balance); }

Now if we run this CHESS will detect a deadlock scenario. If you’ve done some SQL queries you know you should always try to lock all your resources always in the same order. But why doesn’t it working here. We have only one method that lock resources they should be locked in the same order every time, and that’s true. The deadlock occurs because in some cases a thread start to lock the fromAccount (or maybe the toAccount too) and get interrupt by another thread trying to do the same. Then both thread are waiting for each other to complete. Databases engine use timeouts to get out of these situation, but the lock keyword doesn’t support timeout, eventough it uses Monitor.Enter which support it. In another post I will show you how to build your own lock implementation that support timeout, but now we need to find a way to make our code thread safe.

We have to go back to our account class and do some changes.

public static object _locObject = new object();

public static void Transfer(double amount, Account fromAccount, Account toAccount)
{
    lock (_locObject)
    {
        fromAccount.Withdraw(amount);
        toAccount.Deposit(amount);
    }
}

We have to create a static lock object we can use to lock on. Because we are doing the lock in one signle operation our test will now run without any problem.

This is only a small overview of what CHESS can do.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses

May112009

How to test your multi-threaded code (part 2 of 3)?

Published by eric at 7:22 AM under C#

Previously we saw how to build a test to find a multi-thread bug our your code. Now we will look at how to reproduce debug and fix it.

Remember our bank account class:

public class Account
{
    public double Balance { get; set; }

    private Account(double amount)
    {
        Balance = amount;
    }

    public static Account OpenNew(double amount)
    {
        return new Account(amount);
    }

    public void Deposit(double amount)
    {
        double tempAmount = Balance;
        // potential problem
        lock (this)
        {
            Balance = tempAmount + amount;
        }
    }

    public void Withdraw(double amount)
    {
        double tempAmount = Balance;
        // potential problem
        lock (this)
        {
            Balance = tempAmount - amount;
        }
    }
}

And our test:

[TestMethod()]
[HostType("Chess")]
public void BalanceMutiThreadTest()
{
    Account account = Account.OpenNew(10000);

    Thread thread = new Thread(a => ((Account) a).Withdraw(100));
    thread.Start(account);
    account.Deposit(100);
    thread.Join();

    Assert.AreEqual(10000, account.Balance);
}

Now if we look carefully at the test result detail, there is an explanation on how to reproduce this particular schedule. All you have to do is to copy/paste the code provided just before your test method call.

[TestMethod()]
[HostType("Chess")]
[TestProperty("ChessMode", "Repro")]
[TestProperty("ChessBreak", "BeforePreemption")]
#region ChessScheduleString (not human readable)
[TestProperty("ChessScheduleString", @"bpilaiaaaaaaaaaaaeaaonlnahgabmejjgcfcgcpgnmkhlhpekpfeknhoahekbaiiagabdcenijaeabaommbiimnogjcombngjehcdcjklckibmkgffggffnggbgeammonjnlmphnohloplnphnohloplnphlkdljneochphnpppdpfmgggeabgmpgmoeknkmjjocbiakkmibpdphohmbpdpcchomnfpodnhpidfpappfpfhhpponplpkgpmdelpppbgpkplkpoflfmbopdpkgdppbppfpephpocllfpedhppkopjkppjlohpppohpaaldcaoojfhfaaaaaa")]
#endregion
public void BalanceMutiThreadTest()
{
    Account account = Account.OpenNew(10000);

    Thread thread = new Thread(a => ((Account) a).Withdraw(100));
    thread.Start(account);
    account.Deposit(100);
    thread.Join();

    Assert.AreEqual(10000, account.Balance);
}

(your code may be different)

With that code in place if you run your test again (without the debugger) you will see that only one schedule was evaluated and you got the same result as the previous test. From there, as a tester, you job is done. You check in the code and hand it to the development team. If you are a member of a small team, as I usually am, you may be the tester and the developer so you’ll have to debug the code yourself.

Now run this test again but this time with the debugger. The execution should stop just before one of the lock statement. If you step once you will be able to inspect tempAmount and Balance values and see the problem. Between the line where the debugger stop and the previous line another thread changed the Balance value. Now you can see the don’t match.

Of course in this case the solution is easy, we just have to put the tempAmount assignation inside of the lock block but in the next post you will see a case where the solution is not so obvious.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 1 Responses

May062009

How to test your multi-threaded code (part 1 of 3)?

Published by eric at 7:25 AM under C#

CHESS is the answer. At least this is what we have best right now.

In multi-threaded application, bug are hard to almost impossible to find. For the last years the only true way to detect threading problems was to run load test until the system crash. Once it does, every once in thousands of iterations, the tools to reproduce and debug the problem were inexistent.

The RiSE (Research in Software Engineering) team at Microsoft have been working for a long time on a product called CHESS. When run with CHESS, you unit tests will try every possible combination of thread interleave to find a case where you application crash or worst doesn’t give you the result you expect.

Here is a simple demo to show you the power of CHESS. Let’s start with a banking account management system.

public class Account
{
    public double Balance { get; set; }

    private Account(double amount)
    {
        Balance = amount;
    }

    public static Account OpenNew(double amount)
    {
        return new Account(amount);
    }

    public void Deposit(double amount)
    {
        double tempAmount = Balance;
        // potential problem
        lock (this)
        {
            Balance = tempAmount + amount;
        }
    }

    public void Withdraw(double amount)
    {
        double tempAmount = Balance;
        // potential problem
        lock(this)
        {
            Balance = tempAmount - amount;
        }
    }
}

Of course I voluntarily introduce “potential problems” to show how CHESS will get them. With that class you can write this test:

[TestMethod()]
public void BalanceTest()
{
    Account account = Account.OpenNew(10000);

    account.Withdraw(100);
    account.Deposit(100);

    Assert.AreEqual(10000, account.Balance);
}

This will always run fine as it is single threaded. Now what if we change it a little to make it multi-threaded:

[TestMethod()]
public void BalanceMutiThreadTest()
{
    Account account = Account.OpenNew(10000);

    Thread thread = new Thread(a => ((Account) a).Withdraw(100));
    thread.Start(account);
    account.Deposit(100);
    thread.Join();

    Assert.AreEqual(10000, account.Balance);
}

As you can see here we put the withdraw part in a new thread. But even then we can run this test again and again without any problem. You can put it in a loop if you want and never being able to make it return an invalid balance.

Once you have CHESS installed on your system the only thing you have to do is to add a HostType attribute to your method.

[TestMethod()]
[HostType("Chess")]
public void BalanceMutiThreadTest()
{
    Account account = Account.OpenNew(10000);

    Thread thread = new Thread(a => ((Account) a).Withdraw(100));
    thread.Start(account);
    account.Deposit(100);
    thread.Join();

    Assert.AreEqual(10000, account.Balance);
}

Now when you run this test you should get something like:

Assert.AreEqual failed. Expected:<10000>. Actual:<10100>.

You should also have noticed that it took a little longer to run the test. This is because the CHESS host scans your code to build an execution schedule for every possible thread interleave that CHESS can detect. If you double click on the test result you will see how many schedules that were tried before finding the bug, in my case it is 3.

Next time we will see how to reproduce and debug that code.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 3 Responses