Sunday, January 06, 2013

A New Camera


Rach gave me a new camera for Christmas and it's rekindled the interest in taking better photos. I know you can probably only go so far with a point and shoot camera, but I would like to go there... and I figure "there", is still a whole lot better than where I currently am.

I'd like to take photos good enough to print and hang around the house. I'm learning, slowly, and intend to develop the interest to a point where I really do need a "proper" DSR camera.

So I've started with the free lessons that came with the camera, from Camera World, and also stumbled across some helpful tips from David Peterson and www.digital-photo-secrets.com.

Wish me luck!

Tuesday, June 19, 2012

My Windows Azure Tangent

I lost a couple of days earlier this week when I decided to look into alternatives to us hosting our own web site in house, which is basically just a little DotNetNuke site these days, but many moons ago, well before the plethora of Content Management Systems that are available today, we had a very cool ASP (Classic!) site with CMS capabilities, before anyone knew what is was. (I'm talking 1998.)  Anyway, the rest is history, and remnant of that system remain, and we still rely on sharing one portion of the back end SQL database, with an in house app.

I looked into a few hosting solutions which provided DotNetNuke. They were all awesome and clearly selecting one of these very affordable hosting solutions is the way to go. Unfortunately, throwing our SQL database into the cloud, and running our ancient VB6 app against it, was going to impact performance too much at this stage. Suffice to say, some re-factoring (rewriting) of that old app is now on the agenda so we can get some stuff that ought not to be in house, out of house!

Along the way though I signed up for a three month trial of Windows Azure, only to discover when I logged in using my Windows Live ID, the same Windows Live ID that links to my MSDN Premium subscription, that I receive a Windows Azure account along with that subscription. Hadn't realised that, but how good is the sign up process that just realised it all for me.

Now I can build web sites / web servers etc on Azure. Looks like that might just be the way to go next. After a day or so of playing I'm quite excited about the prospects, but for now it's back to the day job before someone notices... but I have got a few things I'm busting to try out.

Unfortunately though, correct me if I'm wrong but it doesn't look exactly straight forward to move an existing SQL Server database onto SQL Azure. Certainly not a simple as a backup and restore, as I had originally hoped.

A generic error occurred in GDI+.

This week I've been focusing again on a utility I'm building to convert data from our old system to our new one - once that new one is in fact ready.

Anyway, this week I've been looking at some memory issues and the wonderful "generic error in GDI+" error I've been seeing crop up occasionally during the conversion process.

One part of the process, load l lot of small images out of a database, for writing straight back into a new database. The image data is read in as a byte array, from the byte array into a MemoryStream, which is in turn used to build an Image object, (Image being a property of one of the business entities) which is then saved. (The conversion process makes use of the business components, entities and data access classes already built to do this.)

So in trying to hunt down some out of memory error messages during this portion of the conversion, I"ve worked back through the code that manipulates the images to ensure objects are disposed of when they should be. I wrapped some portions of the code in using statements and noticed some small improvements. Until, that is, I wrapped a MemoryStream object in one particular innocuous looking private function in a using statement in order to ensure that stream object was disposed of quickly as it was called repetitively.

The job of that function was to take a byte array and give me back an Image.

Originally:


        protected System.Drawing.Image getImageFromByte(Byte[] img)
        {
            System.Drawing.Image returnValue = null;
 
            if (img == null)
                return null;

                System.IO.MemoryStream stream = new System.IO.MemoryStream(img);
                returnValue = System.Drawing.Image.FromStream(stream);
 
            return returnValue;
        }

Became this;

        protected System.Drawing.Image getImageFromByte(Byte[] img)
        {
            System.Drawing.Image returnValue = null;
 
            if (img == null)
                return null;
 
            using (System.IO.MemoryStream stream = new System.IO.MemoryStream(img))
            {
                returnValue = System.Drawing.Image.FromStream(stream);
            }
 
            return returnValue;
        }


After that small change, every call to access the image that was returned by this function, failed with a "Generic GDI+ error" exception.

Once again, Stackoverflow to the rescue:
http://stackoverflow.com/questions/3845456/loading-an-image-from-a-stream-without-keeping-the-stream-open


Turns out, the Image object keeps a reference to it's core Stream object for optimisation purposes, so that when it is disposed, before the image is, you're in a world of trouble.


This article helps explain why: http://support.microsoft.com/Default.aspx?id=814675

The answer? I chose the non-indexed method - it just seemed easier...

        protected System.Drawing.Image getImageFromByte(Byte[] img)
        {
            System.Drawing.Image returnValue = null;
 
            if (img == null)
                return null;
 
            using (System.IO.MemoryStream stream = new System.IO.MemoryStream(img))
            using (System.Drawing.Image imgFromStream = System.Drawing.Image.FromStream(stream))
            {
                // Image object requires the MemoryStream be kept open - work around, create a new non-indexed image
                
                // Set the newImage being created to the same size as the original image
                System.Drawing.Bitmap newImg = new System.Drawing.Bitmap(imgFromStream.Width, imgFromStream.Height);
 
                using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(newImg))
                {
                    // Draw the imgFromStream onto the newImg graphics object
                    g.DrawImage(imgFromStream, 0, 0);
                }
 
                returnValue = newImg;
            }
            
            return returnValue;
        }



Friday, May 25, 2012

Keep it real

As so often happens, a recent post by Seth Godin titled "Hard Work on the Right Things" struck a chord with me.

I'm so guilty of concentrating on the wrong things, and even more often, focussing on the wrong things at the wrong times.

Customers (of the "end user" variety") and even managers, especially in the building industry, don't care about your code, how good it is, what language it's written in or whether your curly braces line up. They don't want to hear you talk about how well architected your system is. They want to know it works, and they want to know it does what "they" want it to, and nothing else.

Most of the time, "what they want it to do" is different to everyone else, and most of the time they can't understand why on earth any other customer would be different, but most importantly, they don't care. It doesn't matter.... to them.

What your software could do for them, and how well it could do it, are completely irrelevant. They are interested in knowing what they want to know right now - be that a problem a prospective customer is trying to solve, or an issue an existing customer on the phone to help desk, is trying to resolve, of a non-technical manager wanting to know when your latest project is going to be ready.

I know what Seth is getting at in his post is intended to apply to any discipline, in any industry with any customer, but I find it is particularly relevant to a developer especially one who is in close contact to the end user of their software.

This is not to say robust, well designed code isn't important or that refactoring your code to make it maintainable, optimised etc isn't vital. It is. Clearly! These just aren't things the customer is interested in (usually).

Likewise, as Seth says;
"what matters changes by culture, by buyer, by product, and even by day of the week". 
The message I take from Seth's post is (in my world) "work hard at building good quality software but be especially attuned to what really matters to the customer/manager/colleague/prospect/friend you are currently interacting with, and relate to that and you'll be a winner."

This has parallels with listening with empathy and "seeking first to understand, then be understood".


Monday, May 21, 2012

Am I "Enjoying the Journey"?

Personal Blogs: a mixture of a personal diary, opinion posts and research links.


I've often heard the advice that all developers should write a blog. Jeff Atwood calls it sharpening the saw. Hey, I'm a massive "7 habits" fan, so what on earth am I doing here?

I started this blog over 8 years ago. I just read the first post - back then I thought my career was heading towards project management. I was working at a fairly large company and learning about leading small teams. I loved it there, but it didn't work out there. I made a lot of good friends that I still keep in touch with, but there's been a few twists and turns since then. I still think I started the blog with the right attitude though - "a little to say and a lot to learn..."

The title of my blog says, "enjoying the journey", but I've never really kept up any form of discipline with regards to this blog. I have enjoyed the journey, but this blog doesn't have a lot to show for it.

Now I do believe there is great benefit to be had in documenting one's work,  ideas and even some personal stuff. I've read where, in order to blog successfully you need a strict plan, a timetable for blogging. I'm not sure that's what I want though. I'm not trying to build an audience. I'm trying to clarify and record.

One other major inhibiting factor, and possibly excuse, for my lack of blogging and the tumbleweeds scattered around my site, is the fact that in my mind, I'm just a "Winforms developer". I've found myself back at a small, software vendor (the very definition of the term Micro-ISV) who is still desperately playing catch up in a technical sense, in a market which, thankfully, isn't demanding cutting edge, high-tech solutions in the line of business software...yet. Our software product is a line of business application that includes accounting and is marketed to very small businesses. In general they want a product, that comes on a disk that they can touch and feel, with a manual or two, and that they can install on a PC in their office.

The product we currently sell (and maintain for an annual fee) is written in VB6. For the last 3 years, I've dedicated around 75% of my time to a complete rebuild of the system on the .Net platform.  The redevelopment started about 2 years before that to be honest, but never got any traction until about 3 years ago. Now, when you say that out loud, it sound ludicrous. But when you live it, every day, for some reason, it doesn't feel like a death march project. I am rebuilding, from scratch a system that was built over three or four years, by a team of three or four developers, on my own and I'm really close to finishing. I have a detailed development and implementation plan for these final stages - much more detailed than the broad brush strokes of a plan I've been working towards until now. I am accountable to the owner of the company and we're all on the same page as to why this is needed. Essentially the product badly needed re-architecting, in order for us to be able to start thinking about web based solutions for our customers and of course now, mobile device apps. This massive project, is the enabler for all this - it's future proofing us.

Back to my point about this blog - my feeling has always been, what value could I possibly add to the Internet, by blogging about my WinForms work?  Once this product is released, it's still going to be about 8 years behind the times. That's about how old the VB6 app was, when I started this.

But now I'm looking at things a bit differently. If I'm going to catch up again, if I'm going to expose myself to the world of web and mobile development (I have done a little of that in the past by the way) I'm going to need to put some "skin in the game" - to get a bit accountable, to myself and to the general public. This blog can achieve that.

There is another side to this too - while I love to listen to and read the likes of Hanselman, Atwood, Spolsky, Godin etc, it's quite a high standard that they set. There is quite possibly a large, probably silent, majority out there in a very similar situation to myself. Maybe, in addition to gaining all the aforementioned benefits of documenting the journey, the lessons, the opinions (as they form) and so on, just maybe, I may even add a little value to the Internet somehow after all.

So bring in on blogosphere. Start teaching me your lessons.

Oh yeh - the building tag

I just noticed the building tag I'd started using for posts about two and half years ago...

BTW - we did it.


Tuesday, December 27, 2011

A WTF from Google!

I guess, because it's Google, I just expected better...