A Day in the Life

A day in my life. Thoughts on leadership, management, startups, technology, software, concurrent development, etc... Basically the stuff I think about from 10am to 6pm.

8/06/2008

Cackl.com…The Yokes on You

A buddy of mine just created a joke site and wants to get the word out to folks and I was one of those tapped to blog about it. It's still a work in progress so post your ideas for improvement here and I'll pass them on to Mike and his team. Otherwise, enjoy and…if you're a jokester…post a few of your own.

Cackl

7/10/2008

Out and About – July 15th, North Bay .NET User Group

I'm heading up to Sebastopol next week. The talk is titled Threading: Back to Basics and I'll be covering how threads work, .NET specific thread stuff, decomposition, and tip and tricks. You can sign up here for the North Bay .NET User Group. Make sure to sign up so they have a good head count.

5/28/2008

Comcast? Internet? Huh?

One would think in this day and age that an Internet Service Provider would understand how the Internet works. But apparently Comcast doesn't have a clue. Not only was I NOT notified that their system would be down…they also don't seem to know how to brand their own 'under construction' page to let their users know what is going on…

After I got a hold of a tech support person, who was rude, there was no estimate as to when I would get email back. Thanks Comcast because not having access to my email is a really big deal for me. I mean it's not like I’m not trying to run a soccer team, a hockey team, play on a hockey team, run a .NET user group, or coordinate a dozen other things that I need to manage in my spare time which…wow…just happens to be at 10:30pm.

Doesn't it actually look like they lost their URL? or that there are a bunch of DNS servers offline?

Click to view image...



Update: Comcast hacked I actually suspected something like that but the Comcast rep told me the site was "down for maintenance". I hate liars. Come on folks a little honesty please.

12/17/2007

VS2005 C++ Build Error vc80.pdb

Are you getting the errors:

Could not delete file ‘c:\myproject\obj\release\vc80.pdb
Make sure that the file is not open by another process and is not write-protected.
Could not delete file ‘c:\myproject\obj\release\vc80.idb
Make sure that the file is not open by another process and is not write-protected.

Then maybe you have the problem described here.

Another solution is to change the number of processes you allow the build process to use.

1. From the VS2005 IDE menu bar select: Tools.Options.Projects and Solutions.Build and Run.
2. On the Build and Run page set the "maximum number of parallel project builds" to 1.

Problem solved.

12/13/2007

AVIFileOpen returns 0x8004406d…

So what does it mean? I was trying to open a .wav file to merge into my AVI stream. After a bit of running around I found that my .wav file only contained a header…no data. And this is why the AVIFileOpen was failing with the return code AVIERR_FILEREAD.

Not a very good error message because the Microsoft documentation says the error indicates, "A disk error occurred while reading the file."

Which is not the case.

10/24/2007

Out and About – Oct 28th, Silicon Valley Code Camp

I'm giving two talks again this year at the Silicon Valley Code Camp. The first talk is at 9:15am and called "Architecture- Building Commercial Apps for Success". I'm going to talk about the things I've learned over the last 20 years delivering commercial apps for startups and small companies. You will learn about my techniques and I will explain to you why those techniques work. This is a high-level talk, no code, but the process has never failed me.

The second talk starts at 10:45am in the same room as the first talk. This will be an "Introduction to Threading" talk for people new to threading. All code samples will use C# but the talk is not language specific. The information is relevant to any developer new to threading on a pre-emptive multitasking operating system.

So…if either of those sound interesting to you follow the Code Camp link and register.

9/28/2007

OnUserPreferenceChanged Hang

You think your code is clean and all is well in the world when all of a sudden your users are starting to report that your application is hanging. You research the issue and discover that from time to time your application hangs when it receives a WM_SETTINGCHANGE message or an OnUserPreferenceChanged event. Ivan Krivyakov did a very thorough write up of what's happening which you can find here. And Microsoft is supposed to have a knowledgebase article out soon about this.

We just ran into this problem and we have learned a few things beyond what Ivan presented. First…did you know that in .NET 2.0 when you create a Control or Form (window) object…it really doesn't exist? For performance reasons Microsoft delays the actual window creation until the window becomes visible or a handle request is made. On the surface this looks innocent enough but if you took the time to read Ivan's report you realize that the final action of window creation may NOT happen on the main UI thread. Where you probably started it.

And don't think you're going to get a CrossThreadException on this one. Even with the CheckForIllegalCrossThreadCalls flag set no exception was thrown. Nor was an exception thrown when the application encountered this problem outside the debugger. Which the documentation says should happen.

Ivan's Freezer code worked very well (he has a link on The Page for some code, you'll want that) and made it very easy for me to reproduce the problem. So step one whenever debugging something like this is to reproduce it on the developer's machine. Freezer enables just that.

Force Window Creation

One thing that Ivan's write-up didn't make clear to me was how to get around this problem. I have confirmed from the Microsoft support guy (Trevor) that the code below will work if you've identified the correct window.

You basically have to force the window creation and you can do that in one of two ways: 1) make the window visible with a Show() or 2) request the Handle. I used the code below:


List lstHandles = new List();
IntPtr hTemp;
foreach (Control myCtrl in Controls)
{
hTemp = myCtrl.Handle;
lstHandles.Add(hTemp);
}

hTemp = Handle;
lstHandles.Add(hTemp);
lstHandles.Clear();


I put the handles in a temporary buffer because I wasn't sure if the optimizing compiler would drop a simple assignment loop like this:


IntPtr hTemp;
foreach (Control myCtrl in Controls)
{
hTemp = myCtrl.Handle;
}

hTemp = Handle;


Identifying the Hanging Window

We had not correctly identified the problem Window. To do that we needed Trevor's suggestion which sent us down the correct road. Trevor suggested using Spy++ to identify what threads our windows were running on.

This was a new use case for me (with Spy++), I had already thrown Spy++ out as a tool for this problem because with Spy++ running the hang hung my entire desktop and nothing worked but the good old three finger salute, to get a Task Manager up.

The trick was to not start Spy++ until we were ready to run the test. So I got my application to the area I knew would hang (with the help of Freezer), and then started Spy++. Once in Spy++ you'll want to do the steps below to find that "bad" window:

1. Select Spy->Processes
2. In the Process dialog find your process
3. Expand your process
4. Expand the threads with the + sign
5. Look for GUI elements on those threads. If you find an element on a non-UI thread...you have found culprit.

You might think that it would be obvious and clear where all your windows are but that wasn't the case for us. Down in our audio code an engineer had created a window to pass to the SetCooperativeLevel(). This was the problem window. A window with no title…so we basically stepped through the process until we saw that Spy++ now contained a window on a non-UI thread.

What was interesting here is that the Window was actually created much earlier but only finished being created on the call to SetCooperativeLevel(). So once we discovered where the system thought the window was created we had to back up the callstack to find the actual window creation location.