Programmers Unlimited

Knowledge is power

  • PostSharp Principals
  • My Articles
  • Projects
  • Archives
  • About

PostSharp with projects targeted at x64

Posted by programmersunlimited on January 27, 2012
Posted in: General. 1 comment

I’ve been working with a project that processes a large set of data so I’m targeting x64 only. I needed to apply my performance and logging aspects to check execution times of each method but when I went to compile I received a build error from PostSharp

“Platform mismatch. You cannot run PostSharp on a 64-bit application from a 32-bit operating system.”

It was obvious that PostSharp was trying to run it’s post processor in x86 mode because my OS is 64-bit and the project is targeting x64 only. The question was “how do I tell PostSharp to work in x64 mode?”. The answer to resolving this issue is pretty easy because the developers at SharpCrafters have come through once again with great tooling for their product. You simply need to go into the project properties and click on the PostSharp tab, then set the “Processor Architecture” to x64. After that, you’re good to go.

ps-tab

What else can you do in here? Well you can also enable/disable PostSharp, enable/disable support for obfuscation and pass in additional properties to PostSharp just to name a few.

If you don’t have the latest version of PostSharp, grab it from PostSharp 2.1 and if you’re new to AOP or PostSharp, have a look at PostSharp Principals to quickly get to speed with PostSharp.

  • More

Like this:

Like Loading...

DataTables != Thread Safe

Posted by programmersunlimited on January 26, 2012
Posted in: General. 3 comments

The title of this post might seem really silly considering MSDN specifically says they aren’t thread safe, but there’s more to it than that. It says DataTables are not thread safe for WRITE operations which is a major ‘”Duh” statement, but in reality they are not safe for some read operations. I’ve been having some strange issues with DataRows in parallel loops so I started to investigate.

I saw a post stating that DataTable.Select() is actually a write operation so it isn’t thread safe and requires a lock. I don’t see anything on MSDN about this. So I got to thinking and that’s when I opened up dotPeek. What did I find?

DataTable.NewRow() is not thread safe! The point of this method is to create a new row with the same schema as the table. According to MSDN you have to then add that row to the table’s DataRowCollection, it is not automatically added to the row collection when calling NewRow(). This, for the most part, is a read operation which would be thread safe. BUT, at one point in the internals, a call to NewRow(int) is made which creates the new record object, then sets that record to a class scoped field before passing it along to a DataRowBuilder. This is where it is no longer thread safe.

I was seeing so many problems because I was using NewRow() in a parallel loop and data was being corrupted at the end. This was why. To combat this, I generated a cache of new rows before the parallel loop, in a ConcurrentBag<DataRow> and then use a TryTake() inside of the loop. No more problems.

  • More

Like this:

Like Loading...

Change Request Pattern – Parallelism and non thread safe collections

Posted by programmersunlimited on January 24, 2012
Posted in: General. Leave a Comment

My current project makes heavy use of DataTables and parallel processing via the TPL. DataTables are not thread safe and really bite the dust hard when asked to do more than one thing at once.

My project breaks up operations that need to be performed on a DataTable into groups that can be executed concurrently. In total that are about 15 groups each with 2-5 concurrent processes. Each process works with certain columns on a DataRow but still, the DataTable can’t handle more than one change request at a time or it just has a stroke. It’s very annoying. I could easily combat this by using POCOs instead of DataTables but it isn’t an option. So how do I do it? Using what I call the Change Request pattern.

The concept is simple, there are operations reading and making changes to each row in the DataTable. Usually data correction, number crunching, etc. Instead of writing the new value back to the DataColumn, it queues up the change in a thread safe collection using a POCO to describe what has to change. When the operations in the group have finished, the changes are processed one-by-one in a thread safe manner.

private void DoWork(DataTable table)
{
    var chgcrd = new ChangeCoordinator(table);
   
    Task t1 = Task.Factory.StartNew(new Action(() => { UpdateColumn1(table, chgcrd); }));
    Task t2 = Task.Factory.StartNew(new Action(() => { UpdateColumn2(table, chgcrd); }));

    Task.WaitAll(t1, t2);

    chgcrd.ProcessChanges();
}

private void UpdateColumn2(DataTable table, ChangeCoordinator changes)
{
    Parallel.For(0, table.Rows.Count, new Action<int>((i) =>
    {
        int oldValue = table.Rows[i].Field<int>("column2");
        int newValue = oldValue * 5;
        long rowId = table.Rows[i].Field<long>("id");

        changes.ScheduleChange(new ChangeRequest(rowId, "column2", newValue));
    }));
}

private void UpdateColumn1(DataTable table, ChangeCoordinator changes)
{
    Parallel.For(0, table.Rows.Count, new Action<int>((i) =>
    {
        int oldValue = table.Rows[i].Field<int>("column1");
        int newValue = oldValue * 2;
        long rowId = table.Rows[i].Field<long>("id");

        changes.ScheduleChange(new ChangeRequest(rowId, "column1", newValue));                
    }));
}
public class ChangeRequest
{
    public long ID { get; set; }
    public string Column { get; set; }
    public object Value { get; set; }

    public ChangeRequest(long id, string column, object value)
    {
        this.ID = id;
        this.Column = column;
        this.Value = value;
    }
}
public class ChangeCoordinator
{  
    public ChangeCoordinator(DataTable table) 
    {
        _table = table;
    }

    private ConcurrentBag<ChangeRequest> _changes = new ConcurrentBag<ChangeRequest>();
    private DataTable _table;

    public void ScheduleChange(ChangeRequest request)
    {
        _changes.Add(request);
    }

    public void ProcessChanges()
    {
        ChangeRequest cr;
            
        while(_changes.TryTake(out cr)) 
        {
            var row = _table.Rows.Find(cr.ID);
            if (row == null) { continue; }

            row[cr.Column] = cr.Value;
        }

        _table.AcceptChanges();            
    }
}

The code is a dumbed down version of what I’ve implemented, just to show the basic concept. The applications are numerous but I chose to use the DataTable example because it’s a thorn in my side at the moment.

  • More

Like this:

Like Loading...

Indexing DataTables

Posted by programmersunlimited on January 24, 2012
Posted in: General. Leave a Comment

That’s right, I’m still using DataTables. Why? Because they best fit the requirements for what I am doing. I’m also taking advantage of parallel processing via the TPL. A lot of the operations I need to do would be much easier via PLINQ and POCO’s such as joins, grouping and searching.

Because I’m working with many disparate DataTables and the join predicates are complex it just isn’t feasible (performance wise) to use DataRelation. To get a working prototype I decided to just use nested loops to find matching DataRows but I’ve found that nested loops when using the TPL results in poor performance and is generally a bad idea when working with large item sets anyway.

Normally I would build a HashTable and create a key from each row based on the columns in the predicate, then use that to match rows with a single loop. However, when using parallel loops, one has to take care to avoid concurrency/multi-threading issues that arise with non thread safe collections. Dictionary<K,V> is normally satisfactory when using them, but they are not thread safe. ConcurrentDictionary<K,V> would seem like an obvious candidate to replace the normal dictionary, but it buckles under the pressure. Memory consumption goes through the roof even for simple, small data processing and performance takes a serious hit.

Another issue with my row key by column approach is that the code has to be written each time and normally I use string concatenation for the keys. Instead, I wanted a nice way to build an index that I can easily query, but I also wanted a generic solution so any key could be used.

I went with the following method

public static Dictionary<TKey, List<DataRow>> BuildIndex<TKey>(this DataTable source, Func<DataRow, TKey> processRow)
{
    ConcurrentBag<Index<TKey, DataRow>> indexBag = new ConcurrentBag<Index<TKey, DataRow>>();

    Parallel.For(0, source.Rows.Count, new Action<int>((i) =>
        {
            indexBag.Add(new Index<TKey, DataRow>()
            {
                Key = processRow(source.Rows[i]),
                Row = source.Rows[i]
            });

        }));

    var result = (from i in indexBag
                    group i by i.Key into g
                    select g
                        ).ToDictionary(c => c.Key, d => d.Select(e=>e.Row).ToList() );

    return result;
}
private class Index<TKey, URow>
{
    public TKey Key { get; set; }
    public URow Row { get; set; }
}

This method  takes in a generic type TKey to define the index key and then requires a predicate to build the key from each row. The performance of this is excellent. The generic Index model is simply a nice way to organize the keys as things are being built. I chose to return a dictionary because I’m satisfied with the performance and functionality and since it’s only being used for reading and not writing, we don’t need a thread safe collection. I could have easily went with a IEnumerable<Index<TKey,URow>> but why bother?

Since this ends up as an extension method, using it is pretty simple.

private void Loop(DataTable table1, DataTable table2)
{
    //Build index for table2
    var idx = table2.BuildIndex<Tuple<int, long, int>>((dr) =>
    {
        return new Tuple<int, long, int>(
            dr.Field<int>("userid"),
            dr.Field<long>("orderid"),
            dr.Field<int>("domainid"));
    });

    //Loop over table1
    Parallel.For(0, table1.Rows.Count, new Action<int>((i) =>
    {
        var rowKey = new Tuple<int, long, int>(
            table1.Rows[i].Field<int>("userid"),
            table1.Rows[i].Field<long>("orderid"),
            table1.Rows[i].Field<int>("domainid"));

        if (idx.ContainsKey(rowKey))
        {
            //Exists
        }
        else
        {
            //Doesn't exist
        }
    }));
}

private void Join(DataTable table1, DataTable table2)
{
    //Build index for table1
    var idx1 = table1.BuildIndex<Tuple<int, long, int>>((dr) =>
    {
        return new Tuple<int, long, int>(
            dr.Field<int>("userid"),
            dr.Field<long>("orderid"),
            dr.Field<int>("domainid"));
    });

    //Build index for table2
    var idx2 = table2.BuildIndex<Tuple<int, long, int>>((dr) =>
    {
        return new Tuple<int, long, int>(
            dr.Field<int>("userid"),
            dr.Field<long>("orderid"),
            dr.Field<int>("domainid"));
    });

    //Do a join
    var joined = from i in idx1
                    join j in idx2 on i.Key equals j.Key
                    select new { Key = i.Key, t1Rows = i.Value, t2Rows = j.Value };

}

Tuples are great to use as keys because they’re immutable and have a smaller footprint than strings (generally speaking).

Conclusion: If I could use POCOs instead of DataTables I certainly would but for now I do what I can. I find the indexing method I’ve come up with a great way to work around performance and threading issues (even when only reading) of DataTables.

I’m interested in hearing your thoughts.

  • More

Like this:

Like Loading...

Learn T4 with my PluralSight course

Posted by programmersunlimited on January 18, 2012
Posted in: General. Leave a Comment

My new course on T4 (Text Template Transformation Toolkit) has gone live and it’s ready for your viewing pleasure. If you have any feed back, please send it to me.

T4 Templates on PluralSight.com

This course introduces T4, Microsoft’s code generation tool that comes with Visual Studio. The Text Template Transformation Toolkit dynamically produces text of any type and is used for code and document generation.

Discover how to reduce development time, bugs and maintenance by building reusable templates. This course covers T4 template building blocks, extending templates with custom functionality and debugging the template execution process.

MVC and Entity Framework, among others, can be customized and extended through T4 templates. It also covers, how to customize MVC controllers using the default templates and the MVCScaffolding package, and customizing entities by adding validation attributes.

Dustin tops it all off with real world uses of T4 including generating, and automatically synchronizing, code based on external resources, and combining T4 with other technologies to produce powerful templates.

  • More

Like this:

Like Loading...

Exposing internal methods in 3rd party assemblies for external use

Posted by programmersunlimited on August 16, 2011
Posted in: General. Leave a Comment

To start out, I’m going to state that I don’t condone this, but if you need it then you need it. I expect to get some nasty comments about pattern violation this or encapsulation that so go ahead and send them in. This is just an extension of my previous post about modifying 3rd party assemblies and the power of PostSharp.

The Evil API

I was working with an API recently that had me using ILSpy to figure anything out. At some point I needed to make use of some code while inheriting a class and overriding a virtual method. So I copied out some code from ILSpy into Visual Studio when I realized that an important method call was broken because that method was internal only. DOH! Due to reasons I won’t explain, I didn’t actually modify the assembly, I just went another way, but if I could have I would have just exposed the method.

Here is our own little evil API

namespace Example.API
{
    public class Calculator
    {
        public int ProcessValue(int x)
        {
            return SuperSpecialCalculation(x, x);
        }

        internal int SuperSpecialCalculation(int x, int y)
        {
            return x + y;
        }

    }
}

Two methods, a public and an internal. We need access to the internal!

The Apsect and Provider

I’m sure there are better ways, but I decided to just introduce a public method using the same signature as the internal method and it will just act as a wrapper. So we need an aspect that imports the expected internal method (target) and introduces our wrapper method. Then we need a provider to tell PostSharp where to apply our aspect. For more information on aspect providers, see PostSharp Principals day 12 & day 13. For more information on introduction, see PostSharp Principals day 13 & day 14.

namespace InternalToPublic
{
    //Aspect Provider
    public class AspectProvider : IAspectProvider
    {
        public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
        {
            List<AspectInstance> targets = new List<AspectInstance>();

            var targetType = ((Assembly)targetElement).GetTypes().FirstOrDefault(c => c.Name.Equals("Calculator"));

            if (targetType == null) { return targets; }

            targets.Add(new AspectInstance(targetType, new ExposeSuperSpecialCalculation()));

            return targets;
        }

    }

    //Aspect
    [Serializable]
    public class ExposeSuperSpecialCalculation : InstanceLevelAspect
    {
        [ImportMember("SuperSpecialCalculation", IsRequired = true, Order = ImportMemberOrder.BeforeIntroductions)]
        public Func<int, int, int> InternalMethod;

        [IntroduceMember]
        public int SuperSpecialCalculationPublic(int x, int y)
        {
            return InternalMethod(x, y);
        }
    }
}

Modify!

Just as in the previous post, we run a batch file to do the modifications to the assembly.

@"C:\Program Files (x86)\PostSharp 2.1\Release\postsharp.4.0-x86-cil.exe" "Example.API.dll" /p:AspectProviders=InternalToPublic.AspectProvider,InternalToPublic /p:Output=output\Example.API.dll
@copy /y InternalToPublic.dll .\Output
@copy /y PostSharp.dll .\Output
@pause

Test

Now we just need to make sure it’s all working. Create a new project and reference the modified Example.API.dll, InternalToPublic.dll and PostSharp.dll.

namespace Example.TestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Example.API.Calculator c = new API.Calculator();
            Console.WriteLine(c.ProcessValue(10));
            Console.WriteLine(c.SuperSpecialCalculationPublic(10, 20));
            Console.ReadKey();
        }
    }
}

The output is as expected

20
30

kick it on DotNetKicks.com

  • More

Like this:

Like Loading...

PostSharp: Why are my arguments null?!

Posted by programmersunlimited on August 1, 2011
Posted in: General. Leave a Comment

I see this question a lot. The developer has created an aspect and when they are stepping through they are seeing that the advice method arguments are null. The most common example of this is the MethodExecutionArgs.Exception. We can easily reproduce this “issue”.

Example

If you compile this code and step through it, the args parameter will be null.

[LogAspect]
class Program
{
    static void Main(string[] args)
    {
        throw new Exception("test exception");
    }
}

[Serializable]
public class LogAspect : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        Console.Write("There was an error");
    }
}

PostSharpNullArgs1

So what’s going on? Well if you use ILSpy and look at the compiled result, you’ll see that PostSharp uses optimizations that include ignoring unused properties.

PostSharpNullArgsILSpy1

See how the OnException method has been decorated with multiple MethodExecutionAdviceOptimizations flags? The entire list for this aspect is:

MethodExecutionAdviceOptimization(
MethodExecutionAdviceOptimizations.IgnoreGetMethod 
| MethodExecutionAdviceOptimizations.IgnoreSetFlowBehavior
| MethodExecutionAdviceOptimizations.IgnoreGetArguments
| MethodExecutionAdviceOptimizations.IgnoreSetArguments
| MethodExecutionAdviceOptimizations.IgnoreGetInstance 
| MethodExecutionAdviceOptimizations.IgnoreSetInstance
| MethodExecutionAdviceOptimizations.IgnoreGetException 
| MethodExecutionAdviceOptimizations.IgnoreGetReturnValue
| MethodExecutionAdviceOptimizations.IgnoreSetReturnValue 
| MethodExecutionAdviceOptimizations.IgnoreGetMethodExecutionTag
| MethodExecutionAdviceOptimizations.IgnoreSetMethodExecutionTag 
| MethodExecutionAdviceOptimizations.IgnoreEventArgs
)

Notice the IgnoreGetException flag? That’s why it’s null when stepping through the aspect. Change the aspect to

[LogAspect]
class Program
{
    static void Main(string[] args)
    {
        throw new Exception("test exception");
    }
}

[Serializable]
public class LogAspect : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        Exception e = args.Exception; //Now we're using Exception so it won't be null
        Console.Write("There was an error");
    }
}

and rebuild. When you step through this time, args is not null and neither is args.Exception.

PostSharpNullArgs2

Looking at ILSpy again, you no longer see the IgnoreGetException flag.

MethodExecutionAdviceOptimization(
MethodExecutionAdviceOptimizations.IgnoreGetMethod
| MethodExecutionAdviceOptimizations.IgnoreSetFlowBehavior
| MethodExecutionAdviceOptimizations.IgnoreGetArguments
| MethodExecutionAdviceOptimizations.IgnoreSetArguments
| MethodExecutionAdviceOptimizations.IgnoreGetInstance
| MethodExecutionAdviceOptimizations.IgnoreSetInstance
| MethodExecutionAdviceOptimizations.IgnoreGetReturnValue
| MethodExecutionAdviceOptimizations.IgnoreSetReturnValue
| MethodExecutionAdviceOptimizations.IgnoreGetMethodExecutionTag
| MethodExecutionAdviceOptimizations.IgnoreSetMethodExecutionTag
)

Answer

So why are the arguments null? Because you’re not using them.

kick it on DotNetKicks.com

  • More

Like this:

Like Loading...

Posts navigation

← Older Entries
Newer Entries →
  • Microsoft MVP, MCTS, PostSharp MVP,
    PluralSight author, MashThis podcast

    Twitter: @PrgrmrsUnlmtd

  • My Videos

    Ruby on Rails - A Jumpstart for .NET Developers

    Building extensible applications with MEF (series)

    Isolating Code - A quick intro to Typemock Isolator

    Introduction to T4 Templates (series)
  • RSS MashThis Podcast

    • Fiddler with Eric Lawrence
      Lee, Nick, and guest host John Sheehan chat with Eric Lawrence, the creator of the Fiddler web debugger.
    • The NPR API with Javaun Moradi
      As the Product Manager of APIs at NPR, Javaun Moradi is the man who makes sure legions of National Public Radio fans get their fix.
    • Mashape with Augusto Marietti
      Guest host Justin Rusbatch joins the Mash This team to speak to Augusto Marietti, co-founder and CEO of Mashape, the marketplace for cloud APIs.
  • PostSharp Principals

    Day 1 – OnExceptionAspect

    Day 2 - Applying Aspects with Multicasting Part 1

    Day 3 - Applying Aspects with Multicasting Part 2

    Day 4 - OnMethodBoundaryAspect

    Day 5 - Visual Studio Add-ins

    Day 6 Your code after PostSharp

    Day 7 Interception Aspects – Part 1

    Day 8 Interception Aspects – Part 2

    Day 9 Aspect Lifetime & Scope Part 1

    Day 10 Aspect Lifetime & Scope Part 2

    Day 11 – EventInterceptionAspect

    Day 12 – Aspect Providers, Part 1

    Day 13 – Aspect Providers, Part 2

    Day 14 – Introducing Members and Interfaces, Part 1

    Day 15 – Introducing Members and Interfaces, Part 2

Blog at WordPress.com. Theme: Parament by Automattic.
Programmers Unlimited
Blog at WordPress.com. Theme: Parament.
Follow

Get every new post delivered to your Inbox.

Powered by WordPress.com
Cancel
%d bloggers like this: