Sunday, October 15, 2006

'__pendingCallbacks[...].async' is null or not an object

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/__pendingcallbacksasync_is_null_or_not_an_object.htm]

I was doing so ASP.Net 2.0 callbacks (see an overview here: http://dotnet.sys-con.com/read/192509.htm), and kept getting this error when I did a document.location redirect on the ReceiveCallback JavaScript function.

Microsoft JScript runtime error: '__pendingCallbacks[...].async' is null or not an object

Looks like a flagrant Microsoft bug: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101974

People have different suggestions

What worked for me is the setTimeout. However, I needed to pass a parameter to the variable, so I used a technique like so:

var _gRValue;
function ReceiveCallback(rValue)
{
  _gRValue = rValue;
  window.setTimeout('__ReceiveCallback(_gRValue)',0);
}

function __ReceiveCallback(rValue)
{
  //Do stuff here
} //end of method
 

To handle the nature of setTimeout, I stored the returned data in a member variable.

Backwards: "I wanted to do Unit Tests, but my manager wouldn't let me"

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/backwards_i_wanted_to_do_unit_tests_but_my_manager_wouldnt_l.htm]

I've heard this before when I give interviews or meet new developers at tradeshows.  The thinking seems to go that "While I'd personally love to do this best practice of 'Unit Tests', adding them takes a lot longer (like adding a new development phase), which costs extra money, therefore I need managerial approval." This is fundamentally backwards.

The whole point of Unit Tests is that:

  1. They save you time: Obviously with regression testing, but also by stubbing out the context so you can very quickly test things in isolation (without wasting tons of time constantly re-setting up that context). They also help you to see all the boundary test cases, and hence prevent future bugs.
  2. They are free to use - open source tools like NUnit can be downloaded for free and instantly used for your own personal development. It's not like you need to purchase a separate expensive tool, or hire out some auditor to review your code.
  3. You write tests as you develop, not afterwards.

Here's an analogy: Think of your schedule like a bucket, and your tasks are like rocks that fill up the bucket. You can't increase the size of your bucket, or decrease the number of rocks, therefore the bucket (i.e. your schedule) seems full. However, there are gaps between the rocks (just like there are gaps between tasks - like setting up the context and regression testing). You could pour sand into a full bucket, in the cracks in between the rocks. That's what unit tests are like. If you do them as you develop, you can squeeze them into your schedule without overflowing it.

Friday, October 13, 2006

What makes programming fun?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/what_makes_programming_fun.htm]

A brainstorm of some ideas. (Feel free to add your own in the comment section).

  • Writing new, interesting code
  • Not hunting down regression bugs
  • Not repeating yourself
  • Sharing work with others
  • Learning new things
  • Seeing your code just work

Certain methodologies, like Agile and TestDriven.Net are designed to fulfill many of these things. For example, by having sufficient unit test coverage, you minimize your regression bugs and get to focus more on new things.

Thursday, October 12, 2006

The myth of the "perfect past project"

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/the_myth_of_the_perfect_past_project.htm]

In today's world, developers switch projects a lot. Whether it's a consultant at the same company who keeps jumping between 3 month projects, or a developer who switches jobs every two years, most people can refer to some "previous" job. I notice an interesting trend, that some people insist that they've had that perfect project in the past - the one (unlike their current job) where everything was done properly. It almost comes across as their development life was great before (i.e. their last job did it "right"), but their current employer is a bozo. Many people can refer to a good previous project because some other star (not them) made it good. For example, a past project may have had awesome process or tools - but someone else set it up. It seems like a bluff (or the grass is always greener on the other side thinking), but because you don't know about their previous project, and have to just take their word for it. But, you can always ask what they did to make that last project so great, and what they can do on the current team (besides just reminiscing about the "Good old days") to make the current project better.

Friday, September 15, 2006

How to make maintenance easier

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/how_to_make_maintenance_easier.htm]

Almost everyone would rather create something new than fix something broken (especially someone else's broken code). However, it's inevitable that some maintenance will always be required. Here are some ideas to make maintenance easier:

  • Reduce the amount of work that must be maintained by refactoring your code.
  • Add Unit Tests for easier regression testing, and to make sure that your maintenance doesn't break something else.
  • Document your work so that it's easier to understand, perhaps with inline comments (maybe using NDoc), wikis, or more traditional word documents for feature designs.
  • Design you code to be maintainable - perhaps use simpler algorithms (if all else is equal), loosely couple components so that it's easier to understand, make flexible code, etc...

Sunday, September 3, 2006

Creating Database Unit Tests - new install UI

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/creating_database_unit_tests__new_install_ui.htm]

The MassDataHandler is a framework to assist with Database Unit Testing. The framework makes it very easy to insert test data into a database, which in turn makes it very easy to write database unit tests. The user merely needs to specify their relevant data in a simple XML fragment, and then the framework uses knowledge of the database schema to do all the grunt work and convert that XML data into SQL, from which it populates the database.

It is an open-source .Net app available here.

We recently improved the install process for the app by having a GUI form collect environmental info for SQL 2005, MSTest, and MSBuild. The install script uses the concept of Having an MSBuild script collect userinput.

If you're looking to test your data layer, check out this free tool. It's now easier to install.

Saturday, August 26, 2006

Have MSBuild script collect userinput

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/have_msbuild_script_collect_userinput.htm]

MSBuild is great for automated batch processes. It's easy to set properties in the script itself using the . However, MSBuild is powerful enough that you can also collect user input with a WinForm.

Why would you do this, given that the whole point of a build process is to be automated? ... Because MSBuild is an automation language, it can be used not just for builds but to
ultimately automate any task. For some tasks that you kick off manually (like installations, deployments, instrumentation, etc...) you may want to collect the user input up front.

Doing this requires three steps.

  1. Use MSBuild's exec task to call a WinForm exe (that you create with a Windows Form project). Note that you may want to compile the windows project first, and then call the newly created exe.
  2. Have the WinForm app close, returning an error
  3. Back in the MSBuild script, collect this error information and handle it how you want.

The first step is easy, lets look at the second one. There are several different ways we can return error information from a WinForm.

  1. We could throw an exception, but that just pops up a messy JIT window, tells the user that the app failed, and doesn't return an error to the build process.
  2. We could have the WinForm write out to a log file, and then have the MSBuild script fail if that file exists - but that requires extra files and is messy.
  3. We could modify the return code of program.cs (just like you can modify a console app's return code) to return an integer, and that set that int with a static variable. This is our best option of the three - no external files, and the error is handled gracefully.

With this technique, everything becomes easy: Our MSBuild script can be simple:

  "EndPoint">
   
    "WindowsApplication1\WindowsApplication1.csproj"
        Targets="Build"
        Properties="Configuration=Debug" />
   
    "Start UI" />
    "WindowsApplication1\bin\Debug" Command="WindowsApplication1.exe" />

    "Done, do other stuff now..." />
 

The WinForm is easy:

  static class Program  {    ///     /// The main entry point for the application.    ///     [STAThread]    static int Main()    {      Application.EnableVisualStyles();      Application.SetCompatibleTextRenderingDefault(false);      Application.Run(new Form1());      return _intReturnCode;    }    private static int _intReturnCode = 0;    public static int ReturnCode    {      get { return _intReturnCode; }      set { _intReturnCode = value; }    }      }

 

We can then set the static variable "ReturnCode" anywhere in the WinForm by setting Program.ReturnCode.

(Note that we can also have the WinForm use Console.Writeline(), which will be logged in the MSBuild script).

Having the MSBuild script take user input is an easy trick to perform, and may be helpful for certain tasks.