CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Grant Killian's Blog

No, this has nothing to do with beer -- but maybe it should?

August 2003 - Posts

  • Does the SQLClient emperor have no clothes?

    In light of the class Debugging section we just wrapped up, I think it’s good to point out the CLR Profiler as an excellent tool for examining what your .Net application is doing under the hood.  The CLRProfiler takes an invasive approach to monitor what your program is doing on the managed heap – check out Gregor Noriskin’s articles to download the tool and for specifics.

    I was using CLRProfiler to explore my data access code, and I set up the following test to compare OLEDB and SQLClient data provider performance:

    const SQL as String = "SELECT ContactName FROM Customers"

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            'OleDB

             for x as integer = 0 to 10

                listbox1.Items.Clear()

                dim cn as new OleDbConnection( AppSettings( "DSNOLEDB" ).ToString() )

                cn.Open()

                dim cmd as New OleDbCommand( SQL, cn )

                dim reader as OleDbDataReader = cmd.ExecuteReader( CommandBehavior.CloseConnection )

                do while( reader.Read() )

                    listbox1.Items.Add( reader( 0 ).ToString()  )

                loop

                reader.Close()

                x+=1

             next

        End Sub

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

            'SQLClient

             for x as integer = 0 to 10

                 listbox1.Items.Clear()

                dim cn as new SqlConnection( AppSettings( "DSNSQLSERVER" ).ToString() )

                cn.Open()

                dim cmd as New SqlCommand( SQL, cn )

                dim reader as SqlDataReader = cmd.ExecuteReader( CommandBehavior.CloseConnection )

                do while( reader.Read() )

                    listbox1.Items.Add( reader( 0 ).ToString()  )

                loop

                reader.Close()

                x+=1

             next

        End Sub

    Nothing fancy, just a good ol’ datareader iterating over results of a SQL query and filling a listbox.  Everything you read praises the SQLClient for it’s efficiency . . . so when I ran the CLR Profiler I figured I’d see SQLClient looking better than OLEDB.  Here is a glimpse of what I initially saw (numbers averaged over many repetitions):

    • OLEDB method allocates 514 KB to the managed heap, 2 generation 2 garbage collections runs

    • SQLClient method allocates 722 KB to the managed heap, 3 generation 2 garbage collections runs

    On first glance, one might say the smaller heap allocated memory for OLEDB and the fewer GC cycles (which follows from consumption of less heap space!) paints OLEDB in the more favorable light.  SQLClient more efficient?  Does the SQLClient data provider, the figurative Emperor, have “no clothes?”  On closer examination, I found the following in the CLRProfiler’s Histogram for Allocated Objects (over 91KB is the largest metric the grid displayed):

    • OLEDB: 13% of objects exceed 91 KB.
    • SQLCLIENT: 8% of objects exceed 91 KB.

    A significantly higher percentage of OLEDB objects are of the large variety, and I'll make a supposition about this later.  The CLRProfiler just tells us the managed footprints our program creates, so I added a timing mechanism to find the average duration the methods took:

    • OLEDB: 43 Milliseconds
    • SQLCLIENT: 31 Milliseconds

    This is for a simple query, one can imagine how much faster SQLClient is when we attack a more complicated data operation and we bring Stored Procedures into the picture, maybe even some advanced T-SQL . . .

    Let’s review.  If I’m reading the CLRProfiler and Performance Timing tea leaves correctly, the SQLClient provider has a larger managed heap memory footprint (about 1.5 times larger) than the OLEDB provider.  This is understandable since OLEDB is an older technology implemented before the days of the CLR; the OLEDB Provider calls more to the unmanaged OLEDB Windows code and has a smaller managed codebase.  SQLClient, on the other hand, takes advantage of the CLR and is implemented more in managed code than OLEDB.  The smaller OLEDB Garbage Collection runs are a direct result of the smaller CLR footprint created by OLEDB.  These two points alone would make the SQLClient hype look a bit unwarranted . . . until we factor in time.  SQLClient does indeed perform faster, much faster, even in this simple example than OLEDB.

    If we look at the objects allocated by each approach, we see OLEDB creates objects greater than 91 KB in size over 50% more often than SQLOLEDB.  Larger objects are slower to work with than small ones, and perhaps (I don’t know for certain) the OLEDB calls to unmanaged code account for this statistical point.

    The morals of this story are:

    1)       SQLClient certainly is faster than OLEDB; the Emperor has clothes after all

    2)       SQLClient has a larger managed heap footprint

    3)       A larger managed heap footprint does not necessarily mean a slower performing application: in this case, it means the opposite (but this isn’t always the case – try a String vs StringBuilder example)

    4)       The CLRProfiler is a powerful tool for inspecting your application’s internal behaviour

    Check out CLRProfiler and Happy .Netting!

  • "Trying Hardest To Learn"

    Darrel Norton's Random Observation got me thinking . . . he writes

    “The people that probably know the most are also the ones trying hardest to learn.“

    Hmmm.

    It certainly strikes a chord with me.  In the software development field, there is so much to learn and new ideas are popping up faster than IT contractors in India.  I've been part of organizations where some developers seem content to just crank out the same stuff they always have and there isn't much drive to digest new ideas and concepts; I, on the other hand, constantly work (struggle sometimes!) to get a handle on the different ways of doing things.  There is so much out there, it can be overwhelming.  This is partly why www.WeProgram.Net is around!  It provides a venue for developers to share what they've found. 

    Code Magazine's Rod Paddock expresses the same sentiment in his recent editorial.

    The truth in Darrell's quote is that the only way the people who “know the most” got to be that way is by “trying hardest to learn.”  While I don't necessarily consider myself in the “know the most” camp, I sure am in the “trying hardest to learn” camp. I hope to find you in that camp too!

  • Implementation Inheritance, or Interface Inheritance, that is the Question

    We recently covered VB.Net OO topics in our class and the question came up regarding when to Inherit from a base object (Implementation Inheritance) versus when to Implement an interface (Interface Inheritance).  While the two approaches are not mutually exclusive, and can be very powerful when used together, let me share my thoughts on the matter.

    The Inherits keyword brings all the implementation details of the parent class into the derived class; this is an elegant means of code reuse and allows for polymorphism via inheritance.   Take the following object model showing Inheritance:

    Public Class BaseBizObject

        Private _strState as String

        Public Property State As String

            Get

                return _strState

            End Get

            Set( val as String )

                _strState = val

            End Set

        End Property

        Public Sub LogState()

            'save state somewhere...

        End Sub

    End Class

    Public Class PersonBizObject

        Inherits BaseBizObject

        'Specific Implementation of PersonBizObject Methods

    End Class

    Public Class OrderBizObject

        Inherits BaseBizObject

        'Specific Implementation of OrderBizObject Methods

    End Class

     

    All our specific business objects (PersonBizObject, OrderBizObject, and any others we create in our business object layer) implement the LogState behaviour courtesy of the BaseBizObject object.  We only have to write the code to LogState()  in our parent object, and the implementation cascades down to all the derived objects.  If we ever needed to implement new functionality common to all our business objects, all we have to do is include the code in the BaseBizObject and voila, we’re good to go.  This is how Implementation Inheritance works; it’s great when creating a closely coupled pattern of reuse in an object model.  I’ve worked on many projects where we create a base object for whatever application tier we’re working on, just to provide an easy way to implement common functionality (such as LogState()).

     

    The Implements keyword binds a class to a specific contract, but has no impact on implementation; this is an elegant means of code reuse but in a completely different way than the Inherits keyword.   This is also known as “Interface Inheritance.”  Take the following code:

    Public Interface ILoggable

        Sub LogState()

    End Interface

    Public Class PersonObject

        Implements ILoggable

        Public Sub LogState() Implements ILoggable.LogState

            'log Person state to the Person table, text file, whatever

        End Sub

    End Class

    Public Class OrderObject

        Implements ILoggable

        Public Sub LogState() Implements ILoggable.LogState

            'log Order state to the Order table, text file, whatever

        End Sub

    End Class

     

    The ILoggable Interface enforces a LogState() method on every type that implements it.  We don’t have LogState behaviour (i.e. code) we want to share between our PersonObject and OrderObject, but we are interested in binding the objects to the ILoggable contract so that we could write the following code:

        Sub EventHandler()

            Dim objPerson as New PersonObject()

            Dim objOrder as New OrderObject()

            DoLogging( objPerson )

            DoLogging( objOrder )

        End Sub

        Sub DoLogging( loggable as ILoggable )

            loggable.LogState()

        End Sub

     

    Our DoLogging method accepts anything implementing the ILoggable interface and invokes the LogState method.  The DoLogging method is where Interfaces create the ability to reuse code – that is, our sub procedure can contain specific code for acting on the ILoggable interface and we don’t have to add the code into each class that implements ILoggable.  Granted, this is a trivial example, but it’s a very powerful mechanism.  Our Person and Order objects adhere to the ILoggable contract (interfaces are really contracts enforced by the CLR) allowing us to program other objects against the contract instead of the specific objects themselves; this, in turn, allows us to separate our object layers from one another instead of closely coupling all our objects together into a monolithic spaghetti of object relationships.  I implement interfaces much more than I program inheritance models for many reasons, including the following:

    -Interfaces help me identify the intersections of objects in code, which helps me design a more robust solution.

    -Interfaces allow for decoupling of objects (so I don’t need a reference to specific object – I can just reference the Interface type instead).

    -Inheritance models must be very carefully designed to actually be reused.  Anticipating future uses of code is tricky, and writing very generic base objects and chaining them together via inheritance is slow going, complex to maintain, and often unsuccessful anyway.  Determining a contract for behaviour (for example: every ReportObject will provide a method returning a SortedList of Key:Value pairs that my ReportProcessor can interact with …) makes for cleaner design, code and ultimately a higher chance of code reuse.

     

    When considering Inherits versus Implements, remember that in the first case you inherit the implementation, and in the second case you agree to the interface contract. 

     

    Happy .Netting

  • Strange Interface Behaviour in VB.Net vs. C#

    Most of my recent examples have been in VB.Net to benefit the students in my class, but I program more often in C#.  Take the following VB.Net code:

    Shared Sub Main()

        dim obj as ILoggable = new PersonObject()

        MessageBox.Show( obj.ToString() )

    End Sub

    Public Interface ILoggable

        Sub LogState()

    End Interface

    Public Class PersonObject

        Implements ILoggable

        Public Sub LogState() Implements ILoggable.LogState

            'log Person state to the Person table, text file, whatever

        End Sub

    End Class

     

    This doesn’t compile in VB.Net because of the obj.ToString() method call. 

     

    Now consider the following C# code:

    [STAThread]

    static void Main()

    {

          ILoggable obj = new personObject();

          MessageBox.Show( obj.ToString() );

    }

    public class personObject: ILoggable

    {

          public void LogState()

          {

                //nothing

          }

    }

    public interface ILoggable

    {

          void LogState();

    }

     

    Fasten your seat belts, the C# compiles and runs; it displays “personObject” in the dialogbox when MessageBox.Show( obj.ToString() ) is called.  C# Interfaces behave as if they derive from System.Object, while VB.Net interfaces do not.  Where is the interoperability?  Yikes.  This makes Interfaces in C# more powerful since you can interrogate via Reflection. Try:

    MessageBox.Show( obj.GetType().ToString() );

     

    And you’ll see what I’m getting at (it displays the type name personObject).

     

    Score 1 (maybe 2, if you’ve created an elaborate reflection-dependent design) for C#.  Anyone have any insight into why this is?

  • Web Services in hours instead of days, weeks, or longer

    It’s nice to measure programming enhancements in hours instead of days, weeks, or months.  .Net Web Services made my day.

     

    I’ve been working on our ecommerce framework and we recently made the decision to reduce costs by processing credit card transactions in two distinct phases.  Let me share our architecture a bit with you:

     

    We have various front end systems, some in old school ASP, some in ASP.Net, and some as Managed .Net Windows applications.  These front-ends hook into our .Net business object layer for services such as Credit Card processing, Calculating Shipping Info, etc (per Microsoft’s SOA recommendations, these are exposed as web services for the most part).

    On the client applications, we apply the Luhn Formula to validate that the CC number is legit.  Of course, we also validate that name, address, etc must be provided.

    In our business objects, our gateway to the bank exposes a secure API including a two-phase transaction process: phase 1 is Authorizing the Credit Card and amount, phase 2 is Committing the transaction.  In my experience, this is how all credit card gateways operate – but I’ve only worked with a handful of banks and your mileage may vary!

     

    So, as I was saying, we decided to process these two phases separately to reduce our costs.  Phase one, Authorization, will be called through the customer check out process (after we test with the Luhn Formula) while phase two, Commitment, will be called from the Administrative console.   How does this reduce costs, you might ask?  Before making this change, we got a lot of declined transactions due to customer typos (misspelling a last name or transposing a zip code digit) – by the time an employee processed the two phase transaction with the gateway, the customer was long gone.  We ended up having to try and contact the customer (by the way, NOBODY uses a real phone number when registering with a site and email addresses are becoming disposable too – the Mailinator is something Darrell Norton pointed out to me); this was a frustrating and time consuming experience, for the customer and our organization; our business suffered because of it.

     

    Enough preamble . . . you get why we wanted to include the Authorization phase of the transaction in the checkout process.  My point in blogging about this is that our Web Service middle tier made this so friggin easy!  Once I nailed down the code to invoke our Web Service  from ASP classic  . . .

        [warning: classic ASP code ahead, hide your children and valuables]

      Set soapClient = Server.CreateObject( "MSSOAP.SoapClient30" ) 

      soapClient.ClientProperty( "ServerHTTPRequest" ) = True 

      soapClient.mssoapinit( “WebServiceURL.asmx?wsdl” )   

      returnValue = soapClient.MyMethod( “PARAMS” )

     

    Very easy, thanks to the SOAP Toolkit and WSDL standards, although it depends slightly on the Soap Toolkit you use.  I say .Net made this really easy because Visual Studio .Net is a premiere tool for web service development: you can build, test (and debug!), and deploy the services with such ease.  The Authorize and Commit functionality was already implemented in different methods, I just had to expose each as it’s own public method and slap a [WebMethod] attribute in there.  I deployed to our test server and had the whole thing done in hours NOT days.

    Now we’re on to the testing and performance tweaking phase (I also know there are some additional Attributes to employ on the webMethod, but that’s another blog).

     

    Happy .Netting

  • Digesting Shadows vs. Overrides

    As the class I'm teaching moves into OO topics, inevitably the subject of “Shadows” and “Overrides” comes up.  “Shadows” probably wins the award as the oddest sounding  addition to the VB language courtesy of .Net . . . although there is some strong competition from AndAlso and OrElse.  If you want more on this topic, check out this good MSDN piece on Shadows.

    When you’re implementing behaviour in a VB.Net class that’s derived from a base class, you have two options: Shadowing or Overriding. 

    To use Overrides in the derived class, the base class member you’re changing (or replacing) must be declared as Overridable.  This means that if the base class designer doesn’t have the foresight to flag the member as Overridable you can’t use Overrides in the derived class.  I suppose an organization could require every method to include the Overridable modifier before you compile and deploy the code, but that doesn’t seem like a good idea to me for security and other reasons.  My point is, it’s impossible for the base class developer to anticipate future needs to adjust an object’s behaviour in a derived class.

    Enter the “Shadows” keyword.

    The Shadows modifier comes into play when the base class HASN’T been flagged as Overridable.  You can replace any base class method with the Shadows modifier – but recognize that Shadows completely replaces the base class method without regard to method signature.

    If this was all there was to it, this blog wouldn’t be necessary.  The issue grows more complicated because you can use Shadows when a method is marked as Overridable, begging the question: what impact does Shadows and Overrides have on my object’s behaviour?

    The short answer: when working with an object polymorphically, Shadows promotes the variable over the type, while Overrides promotes the type over the variable.

    Yikes, how’s that for a short answer?  An example will shed more light on this; consider the following class structure.
    Public Class IcedTea
     Inherits Drink
     Public Shadows Function Consume() as String
      return "Consuming iced tea"
     End Function
    End Class

    Public Class Drink
     Public Function Consume() as String
      return "Consuming a Drink"
     End Function
    End Class

    Public Class AlphaRomeo
     inherits Car
     Public Overrides Function Drive() as string
      Return "Driving an Alpha Romeo"
     End Function

    End Class

    Public Class Car
     Public Overridable Function Drive() as String
      Return "Driving a Car" 
     End Function
    End Class

    These are two contrived examples of base and derived classes; the Car:AlphaRomeo example uses Overrides; the Drink:IcedTea example uses Shadows in the derived class and nothing special in the base class.  Let’s use this test harness to see these classes at work:
      dim objCar as New Car()
      ListBox1.Items.Add( objCar.Drive() )
      dim objAlpha as New AlphaRomeo()
      ListBox1.Items.Add( objAlpha.Drive() )
      objCar = objAlpha
      ListBox1.Items.Add( objCar.Drive() )

      Listbox1.Items.Add( "---------------------------" )

      dim objDrink as New Drink()
      ListBox1.Items.Add( objDrink.Consume() )
      dim objTea as New IcedTea()
      ListBox1.Items.Add( objTea.Consume() )
      objDrink = objTea
      ListBox1.Items.Add( objDrink.Consume() )

    If you place this code in a button click event and run it, you’ll notice the Car:AlphRomeo example shows the “Type over Variable” behaviour.  Even though the variable is defined as a Car type, when it contains an AlphaRomeo type it uses the AlphaRomeo method.  The opposite is the case with the Drink:IcedTea example, it shows “Variable over Type” behaviour.  When the objDrink variable contains an IcedTea instance, the variable’s method takes precendence over the type.  This is just the opposite of the Overrides modifier and clarifies the short answer: when working with an object polymorphically, Shadows promotes the variable over the type, while Overrides promotes the type over the variable.

    I think the Overrides behaviour is generally more desirable for object models and polymorphic processing (if I call drive on all the objects in a Car collection, I tend to want the AlphaRomeos to process their Drive() method and the regular Cars to process their Drive() method).  There are cases, however, where the Shadows modifier might be appropriate; if a method isn’t flagged as Overridable, of course, you don’t have any choice and have to go with Shadows.  Make an informed decision and know that Shadows promotes the variable over the type.

    Sorry for this but I can’t help it . . . another lesson we can draw from this is that if you’re driving a car and drinking, make sure it’s only iced tea!

    Happy .Netting.

  • Asynchronous Behaviour via .Net Delegates

    In the VB class I’m currently teaching at nights for ITPro, one of the students asked for a “very good example of how and why I might use a delegate.”

    Answering this question without getting into topics way beyond the course curriculum is very tricky.  I considered showing a direct threading technique, but most threading topics are beyond the scope of the class; I finally decided on asynchronous delegates (which still manipulate threads, just not so obviously) since it’s closest to our class material -- plus, I had a sample handy from a recent project.  It’s a vast subject, and this is a very brief treatment . . . but I hope it serves as an example of how and why one might use a delegate.   For a more comprehensive look at this sort of thing, check out this MSDN article; for detailed delegate insight, check out some of Don Box’s blogs (he’s Microsoft’s Mr. CLR!).

    The first programs we write in VB.Net are all very simple and run in linear fashion; statement one executes, followed by statement two, and so on.  Most serious programs, for performance purposes, outgrow this paradigm and adopt asynchronous behaviour in certain situations.  When a process is going to take exceptionally long (or long enough for the user to perceive –- say one second or longer), executing those code statements asynchronously is an attractive solution.  We can use delegates to accomplish it.

    Let’s take a class that handles database querying named “ReadDatabase” and a method with time-consuming database work named “CountStuff”:
    Class ReadDatabase
        Public Function CountStuff( byval SQL as String ) as integer
            dim intOut as integer = new Random().Next( 0, 10000 )
            System.Threading.Thread.Sleep( 5000 )
            return intOut
        End Function
    End Class

    Bare with me here . . . we really aren’t querying a database; we’re using the Thread.Sleep() method to pause the current thread 5 seconds (5000 milliseconds).  This simulates a time consuming database task and the Random number serves as our return value.  This is just a mock object.

    Now we declare our Delegate:
    Public Delegate Function DBWorkDelegate( byval strSQL as String  ) as integer

    A Delegate is just a type-safe function pointer; there’s no implementation (sort of like an Interface).  This parameter list and return type create a contract that the Delegate enforces on any functions it points to; it can't point to anything else.

    Now let’s add a form to our application and add a button and listbox to it; let’s add the following code to the button’s click event:
    Dim obj As new ReadDatabase()
    Dim cb As New AsyncCallback( AddressOf AllDone )
    Dim del As New DBWorkDelegate( AddressOf obj.CountStuff )
    del.BeginInvoke( "SELECT * FROM tblData", cb, del )
    ListBox1.Items.Add( "Starting Thread: " & appdomain.GetCurrentThreadId )

    Whew, this is a lot of new stuff (for our class at least!).  Taking it line by line:
    We declare and instantiate a ReadDatabase object.
    We declare and instantiate an AsyncCallback object.  This object holds a reference to the method that should execute when the asynchronous work is done (our final step is to add this AllDone method).
    We declare and instantiate an instance of our DBWorkDelegate Delegate, passing it the method to execute asynchronously.
    We call the BeginInvoke method on that delegate, passing it the arguments our CountStuff method expects as well as the AsyncCallBack object and the DBWorkDelegate instances.  This will spawn a new thread for the data-intensive work to be done on.
    Finally, we add an item to our listbox for debugging purposes; the appDomain is like a meta-thread for .Net programs (somewhere between a Process and Thread), we use it to get a handle on the ThreadID we’re currently executing on.  When our program runs, we’ll find that there are multiple threads being used behind the scenes in our Delegate invocation.

    Almost done.  We need to add the AllDone method as our callback recipient:
        Sub AllDone( ByVal ar As IAsyncResult )
              Dim del As DBWorkDelegate
              del = CType( ar.AsyncState, DBWorkDelegate )
              ListBox1.Items.Add( "Finished Thread: " & appdomain.GetCurrentThreadId )
              MessageBox.Show( del.EndInvoke( ar ) & " records found" )
        End Sub

    This method will fire when our asynchronous work is done (courtesy of the .Net Delegate plumbing).  Note that the callback method must accept a type of IAsyncResult object, and that we convert it to the specific delegate type we’re using.  We also add an item to our listbox displaying the ThreadID of the asynchronous work.  Finally, to get the return value from our CountStuff method, we call EndInvoke on our delegate; at this point our asynchronous work is done.

    Try it yourself; you’ll find the following:
    After you click the button, the listbox displays something like “Starting Thread: 3724”.  Also notice that you can manipulate your form – it isn’t blocking while the database work takes place (“blocking” is the term used when program execution waits for control to return from a lengthy operation); you can resize your form and, *try this*, click your button several times. 
    Once the asynchronous work is done, you’ll see a dialog box with the random number in it and a new line in the listbox saying “Finished Thread: 2516”.

    If you click the button multiple times in quick succession, you’ll see the starting thread is always the same but the asynchronous thread is different; this can lead to a multithreading conversation, but I’ll save it for another time. 

    I originally concluded the post here, but kind Dutchman Peter van Ooijen pointed out a threading issue with the callback method.  My family happens to be Dutch and we have a funny phrase: if you ain't Dutch you ain't much -- Peter sure is much help in this case!   The fact that different ThreadIDs display in the listbox is a sure fire indication that we've got multiple threads interacting with the User Interface -- this is BAD because it can lead to very hard to reproduce and find bugs).  Only the UI-thread should interract with UI controls; our previous example will work most of the time, but is actually not “thread-safe.” 

    Fortunately, .Net provides a convenient means to “merge“ our callback function into the UI thread.  If we replace our callback method with the following:

            If me.InvokeRequired then 'if we have to merge into the UI thread...
                Dim objArgs( 0 ) as Object
                objArgs( 0 ) = ar
                me.Invoke( new AsyncCallback( AddressOf AllDone ), objArgs  )
            Else
                Dim del As DBWorkDelegate
                del = DirectCast(ar.AsyncState, DBWorkDelegate)
                ListBox1.Items.Add( "Finished Thread: " & appdomain.GetCurrentThreadId )
                MessageBox.Show( del.EndInvoke( ar ) & " records found" )
            End If

    The .Net Form object contains an InvokeRequired method that determines our thread condition; we pass the callback function “AllDone“ as a delegate in the Me.Invoke() method call, and Me.Invoke() ensures our callback method runs in a thread-safe manner.  When InvokeRequired returns false (meaning, we're on the same thread), we can handle our IAyncResult as we did before.  If you run this example, you'll notice that the ThreadIDs are now the same for the “Startng Thread“ and the “Finished Thread.“  You can read Peter van Ooijen's treatment of this subject in a web service example here.

    This is a very practical example of Delegates in action; I don’t know if it qualifies as a “very good” example . . . I’ll have to let you be the judge of that.

    Happy .Netting

  • More thoughts on Garbage Collection

    Ever beat a dead horse?

    Brent Rector of Wintellect discusses Finalizers, sharing how the GC process really behaves and why we should think twice thrice before using Finalizers.  Make sure your design warrants the extra overhead.

    Other highlights from Brent's article include:

    • Despite some semantic parallels, C++ destructors behave very differently than C# destructors (and .Net destructors in general).
    • Using Finalizers can cause a significant performance penalty, especially when one considers the multi-step process (and threads) involved with Finalization.
    • If you must use a Finalizer, keep it as simple as possible.
    • His opinion is that since Java has finalizers, MSFT added finalizers to .Net to match up in a feature-by-feature comparison with Java
    • You can use the Dispose pattern if you want to achieve non-deterministic finalization (I discussed this here)

    If you must use Finalizers in your design, keep them brief and free of exception-throwing code; use the Dispose()    pattern and document your classes so clients know to invoke the Dispose() method appropriately (or with a using statement in c#). 

  • Hampton Roads .Net Community

    The year was 2000. Java was not catching on in the Southeast corner of Virginia (aka Hampton Roads).  On the planet “Washington DC” that I came from, Java was competing neck and neck with the Microsoft COM languages, but Microsoft still ruled supreme in Hampton Roads (as evidenced by the tech recruiters salivating over MCSD credentials and the experience to back them up).  Dispite my latent Java evangelical tendencies, I started working in a Microsoft shop doing web development; deep down inside, however, I thought Java would have been a more powerful approach.  I kept expecting the Java frenzy to migrate to Southeastern Virginia but the projects never materialized.

    Then along came .Net.

    Some called it MS Java (but that name had already been used with J++), but on closer inspection it was actually an improvement on Java and -- this was the clincher -- Microsoft had a powerful tool for wielding .Net in Visual Studio .Net.  VS.Net is much more than a code editor; it's an xsl/xsl editor, a code generator, a WYSIWYG database management tool, a rich deployment package creator.  Coming in BizTalk 2004, VS.Net will also be an intuitive orchestration and map designer.  Even the early Beta's, which I was fortunate to experiment with courtesy of an early adopter project at my client's site, showed a level of integration and sophistication that the Java toolset couldn't match (who cares if the Beta crashed when I tried to use context-sensitive help -- the feature was there and the release version ran fine!).  Tools and development environment support has always been a strength for Microsoft and one lesson we can glean from this is that no matter how powerful your platform/language is, if developers can't efficiently and intuitively work with it, adoption suffers.  Over the last year a blossoming of the .Net developer community in Hampton Roads has taken place.  The friends I met at the original client (the one with the early adopter project) have mostly moved on but we still run in the same circles.

    Paul Laudeman is now in Richmond, and initially turned me on to the blog-o-sphere many months ago.  Darrell Norton just started working with Paul's company and helped start http://www.WeProgram.Net; rumour has it he's considering starting a Richmond .Net user group.  Mark DiGiovanni, still in the immediate Hampton Roads area, also helped start http://www.WeProgram.NetJim Meeker, who I just met a few weeks ago at the WeProgram.Net user group meeting, is active in the local .Net community; I know he's very involved with http://www.hrssug.org/.  There are many other great people in the area, but these are the only bloggers I know of.

    The .Net community in Hampton Roads, while no rival to San Jose or Seattle, is steadily gaining momentum.  For example, in October, IDesign's Brian Noyes is coming to talk about Architecture Patterns and I'm hoping we get a really good turn out (check here for details).

  • Reflecting Further . . .

    Jim Meeker, who showed up at the latest WeProgram.Net user group meeting, points out Reflector for .Net at Lutz Roeder's site (http://www.aisto.com/roeder/dotnet/).  This will let you search, disassemble, and otherwise get your hands dirty with MSIL.

  • Reflecting on Attributes and Metadata

    This post complements a discussion we had in the ODU ITPro class the other evening; it gets into much more advanced topics than a 200 level course warrants, but for those interested folks out there, read on . .  . 

    The .NET CLR (Common Language Runtime) is a bit like a cozy blanket wrapped around our business logic.  Not only is it a class loader and execution environment for our .Net types, it facilitates various forms of security, cross-language compatibility, memory management, type safety . . . and this isn’t an exhaustive list.   In fact, the CLR environment is better than just a blanket – it’s like an electric blanket with a hot chocolate machine and slippers built in!

    Metadata is one of the ways the CLR achieves such a rich set of services to our .Net code.  As programmers, we can leverage this metadata to interesting ends.  If you want to follow along at home, add a button and a listbox to a windows form and include the following in the button click event (since I’m teaching a vb.net class currently, I opted for vb sample code – everything is essentially the same in c#):

    Dim fileSys as New OpenFileDialog()
    fileSys.Filter = "Executables ( *.exe )|*.exe|Assemblies ( *.dll )|*.dll"
    fileSys.ShowDialog()
    Dim assm As Reflection.Assembly = Reflection.Assembly.LoadFrom( fileSys.FileName )


    The .Net Reflection namespace is a powerful mechanism for reading (and even writing!) assembly data. After calling Reflection.Assembly.LoadFrom(), our assm variable can tell us all about the assembly that we browsed to with the OpenFileDialog. Let’s add the following to our button click event code:
    Dim arrTypes As Type() = assm.GetTypes()
    Dim arrAttributes as Attribute()
    Dim objType As Type
    Dim objAtt As Attribute
    Dim objCustAtt As MyAttribute ‘custom attribute


    The above is just variable declarations, with the notable exception of the first line (assm.GetTypes()) where we assign all the types in the assembly to our arrTypes array. Assembly metadata contains detailed descriptions of the types our assembly exposes; Reflection, by using assm.GetTypes(), is our tool to reveal these types.
    Now for the good part:

    For Each objType In arrTypes
    ListBox1.Items.Add( objType.FullName & " Summary" )
    arrAttributes = Attribute.GetCustomAttributes( objType )
    if arrAttributes.GetUpperBound( 0 ) > 0 then
    For Each objAtt in arrAttributes
    Try
    ListBox1.Items.Add( objAtt.ToString() )
    objCustAtt = CType( objAtt, MyAttribute )
    ListBox1.Items.Add( "***Custom Value: " & objCustAtt.Value )
    Catch

    End Try
    Next
    End If
    Next objType


    Assuming we’ve got a listbox (named ListBox1), this code will interrogate the types in the assm assembly and display information about the type. If you run this sample on a .Net windows application you’ll see that there are a number of System.ComponentModel attributes at work. I won’t go into the functionality of those attributes because I want to focus on making our OWN attributes. Let’s add the following class to the project we’re creating:

    <AttributeUsage( AttributeTargets.All )> _
    Public Class MyAttribute
    Inherits System.Attribute
    private _strVal as String

    Public ReadOnly Property Value as String
    Get
    return _strVal
    End Get
    End Property

    Public Sub New( Value As String )
    MyBase.New( )
    _strVal = Value
    End Sub
    End Class


    This is a simple example of a custom attribute with a single public property (named Value); it inherits from the System.Attribute class and uses an attribute of its own (in VB.Net, attributes are contained within < and > tags). With this class added to our project, we can include our custom attribute to any class definitions in our project as follows:

    <MyAttribute( "Some Custom Data" )> _
    Public Class Form1


    Attributes must be on the same line as the class definition (note the line continuation character “_”).

    If you run the program and select the exe that we added our custom attribute to, you’ll see the “Some Custom Data” text displayed in the listbox along with the other intrinsic .Net attributes.

    Why is this significant? It allows us to extend .Net metadata and solve programming problems in different ways. .Net uses Attributes all over the place, two examples being to communicate security conditions and to control design-time behaviour of controls. In my company, we use custom attributes to map data objects to relational database objects (for ex: <DataFieldAttribute( “idProduct” ) >); this way we can decouple our object model from the database. Attributes can offer an elegant solution and, with Reflection and Metadata providing the tools, I recommend keeping an eye out for opportunities to make use of them. They aren’t always the answer, but custom attributes and Reflection are powerful enough to warrant your consideration.
  • Don't Dispose() of the GC!

    I'm teaching a .Net class Monday which covers, among other things, CLR Garbage Collection.  I've taught the topic before and invariably the .Net implementation of Garbage Collection rubs some experienced developers the wrong way.  Non-deterministic finalization is the fancy term for not knowing when an object will be removed from memory.  It means that you can't rely on clean-up logic (releasing database connections, closing files, etc.) running at a specific time -- like when an object simply goes out of scope.  This means you have to take care in writing your clean-up logic.  Programmers from non-.Net backgrounds don't like the unreliable Destructor behavior.

    Our class uses the Microsoft .Net self-paced traning kit as teaching material (ISBN 0-7356-1533-0), and they provide a lab for learning about basic garbage collection; we can start with their example.  You create a class as follows:
    Public Class Demo
     Public Shared Instances as Long
     Public Sub New()
      Instances += 1
     End Sub   
     Protected Overrides Sub Finalize() 'called when GC runs
      Instances -= 1
     End Sub
    End Class

    Then you create a WinForms application as follows:
     1 Button Control
     1 Label Control
     1 Timer Control

    Add the following to the OnClick() button event handler:
     Dim ctr as Integer
     for ctr = 1 to 1000
      obj = new Demo()
     Next

    Add the following to the Tick() timer event (be sure to set the Enabled property to True because Timers default to being Disabled):
     Label1.Text = "Object Instances in Memory: " & Demo.Instances

    If you run this app and click the button enough times, you'll create enough Demo objects in memory to eventually trigger a Garbage Collection cycle (if your computer is decked out with lots of memory, it may take quite a few clicks -- I can create 30,000+ object instances). 

    The moral of the story: nobody can guarantee when an object will be removed from memory which means you shouldn't put "must run" clean-up code in the Finalize() method.  When objects go out of scope, they aren't automatically reclaimed by the CLR; instead, they are reclaimed whenever the Garbage Collection process runs (which is on a low-priority thread).

    The textbook stops there, which often sours experienced developers on the CLR Garbage Collection service because they can't control object behaviour the way they can in other environments.  C# is the same way, so this can't be chalked up as a VB.Net oddity.  Don't get down on the GC, though, just because the book leaves it at that!  Let's modify the example and have some real geek fun. 

    If we implement the IDisposable interface, some interesting things happen.  Consider the following DemoDisposable class:
    Public Class DemoDisposable
     Implements IDisposable

     Public Shared Instances as Long
     Public Sub New()
      Instances += 1
     End Sub   
     Protected Overrides Sub Finalize()
      Instances -= 1
     End Sub
       
     Public Sub Dispose() Implements System.IDisposable.Dispose
      Finalize()
      System.GC.SuppressFinalize( me )
     End Sub
    End Class

    We've added an "Implements IDisposable" statement to the class definition, which means our class will conform to the IDisposable interface.  I'm tempted to get into interfaces and programming by contract here, but that's a subject for another time . . .  Also note the Sub Dispose() method in our new class; a Dispose() method is required by the IDisposable interface.  The System.GC.SuppressFinalize( me ) statement prevents the object from being Finalized a second time by the Garbage Collector (which is unnecessary since we've explicitly done it in the Dispose() method -- it's an optimization).

    In our Windows Application, we could write our button onClick() event handler code as follows:
     Dim ctr as Integer
     dim objDis as DemoDisposable
     for ctr = 1 to 10000
      objDis = new DemoDisposable()
      'do something with objDis . . .
      objDis.Dispose()
     Next

    We've added a call to the Dispose() method which will perform the clean-up for us DETERMINISTICALLY.  Now run the program and note that your objects aren't kept around after the Dispose() method is called.

    This approach is called "The Dispose Pattern." 

    Granted, this Dispose Pattern isn't ideal as programmers must remember to always call Dispose() on objects.  There's no guarantee Dispose will be called (in which case normal non-deterministic Garbage Collection runs its course), but it's a lot better than nothing!

    As they say on the Home Shopping Network (I know a guy who programs for them, by the way): but wait, there's more:

    If you're into C# you can take advantage of the using statement.  If you port the example code to C# you can replace the button onClick event handler code with the following:
     int ctr;
     DemoDisposable objDis;
     for( ctr = 1; ctr< 10000; ctr++ ) {
      using( objDis = new DemoDisposable() ) {
       //do something with DemoDisposable  
      }
     }
    The using statement guarantees implicit calling of the Dispose() method so you don't have to!  There are some other good points to the using statment, but this post is long enough already.  Note that the VB.Net language doesn't have anything comparable to a using statement; score 1 for C#.

    There are some other ways to acheive deterministic finalization, but I'll leave it at that for the time being.

    Hopefully your personal GC process won't destroy the substance of this post the next time you're wrestling with .Net object destruction.  Happy .Netting!

  • Post Number 1

    Sorry, none of my geek creds for the first post. Let's get straight to it . . .
More Posts