Delay's Blog

Silverlight, WPF, Windows Phone, Web Platform, .NET, and more...

Posts
  • Delay's Blog

    When the GAC makes you gack (Part 1) [How something can be both IN and NOT IN the GAC at the same time]

    • 1 Comments

    I recently had occasion to use a particular tool for the first time and found that it didn't work on my machine. This was weird, because nobody else seemed to have any problems running the same tool on their machines. So I set out to determine what was wrong...

    Simplifying things ridiculously for the purposes of this example, I'll note that the tool manipulates ZIP files, has a reference to "vjslib", and is compiled from code that looks something like this:

    using java.util.zip;
    
    class Program
    {
        static void Main(string[] args)
        {
            new ZipFile("file.zip");
        }
    }
    

    (Aside: In case you're wondering what's up with the "java.util.zip" namespace and the reference to "vjslib.dll", I'll suggest that the author of this tool was probably following the recommendations of the article "Using the Zip Classes in the J# Class Libraries to Compress Files and Data with C#" which recommends exactly this approach. You may be aware that .NET 2.0 offers support for compressed streams via the classes in the new System.IO.Compression namespace. However, support for compressed streams is not the same thing as supporting the ZIP file format, so I believe this technique is still relevant.)

    When run on my machine, the tool produces the following output (inadvertent profanity due to default 80-column wrapping of "assembly" removed for your protection):

    Unhandled Exception: System.IO.FileNotFoundException: Could not load file or as*
    embly 'vjslib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
    ' or one of its dependencies. The system cannot find the file specified.
    File name: 'vjslib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d
    50a3a'
       at Program.Main(String[] args)

    That's odd, because my computer DOES have the Microsoft Visual J# Version 2.0 Redistributable Package installed as required (it comes with a Visual Studio Team Suite full install). But it's worth checking the GAC (Global Assembly Cache) anyway, just to be sure that vjslib is present there as we expect:

    C:\Program Files\Microsoft.NET\SDK\v2.0 64bit>gacutil -l vjslib
    Microsoft (R) .NET Global Assembly Cache Utility.  Version 2.0.50727.42
    Copyright (c) Microsoft Corporation.  All rights reserved.
    
    The Global Assembly Cache contains the following assemblies:
      vjslib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, pro
    cessorArchitecture=x86
    
    Number of items = 1

    Yup, it's in there. So why can't it be found by the tool? To try to answer that question, we turn to the Assembly Binding Log Viewer (Fuslogvw.exe). Just run the viewer, enable the "Log bind failures to disk" setting, run the tool again, then refresh the viewer and open the failed binding entry to see the following (abbreviated) output:

    *** Assembly Binder Log Entry  (2006-03-23 @ 10:52:44 AM) ***
    
    The operation failed.
    Bind result: hr = 0x80070002. The system cannot find the file specified.
    
    ...
    
    LOG: Post-policy reference: vjslib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
    LOG: GAC Lookup was unsuccessful.
    ...
    LOG: All probing URLs attempted and failed.

    Hum, that's really odd... We know vjslib is in the GAC, yet it can't be found in the GAC. My machine is correctly configured, has the necessary components installed, and appears to be working fine in every other respect.

    So what's going on here??

    (Stay tuned for the exciting answer in Part 2!)

  • Delay's Blog

    Working hard / hardly working [A bit about my new team]

    • 1 Comments
    My new team (affectionately known as the Agility Team (not to be confused with the A-Team)) is small and new and kind of different from the typical Microsoft team. I've been asked what it's all about, but haven't really had a clear, concise answer until now. My new manager, Shawn Burke, just wrote a post in which he outlines the nature and purpose of the team. He even gives a brief description of our current project which, if you've been paying close attention, was hinted at by Scott Guthrie in a recent post about Atlas. Like Shawn says in his post, this project is pretty cool stuff and I'm really looking forward to seeing what customers do with it once they get their hands on it. "I love it when a plan comes together!"
  • Delay's Blog

    An image is now worth two thousand HTML tags [How to: Use ASP.NET's IHttpHandler interface to display a custom image]

    In a previous post, I referred to some MSDN sample code and outlined the process of creating an ASP.NET page to display an image instead of HTML. As is often the case, the relevant sample code was written to demonstrate a concept rather than to be "production-ready". In one of the comments for that post, Heath Stewart suggested the use of a .ashx file as a more efficient way to do the same thing. This seems like a great opportunity to learn a little more about ASP.NET, so let's give it a try!

    First, a little research is in order - I recommend starting with the documentation for Creating HttpHandlers and following up by learning a little about the corresponding IHttpHandler Interface. Armed with that knowledge, we should be able to convert the modified sample code over to the IHttpHandler interface.

    Begin by creating a new file in the web site directory you were already using. I used Visual Studio's "Add New Item" action to add a "Generic Handler" page that was automatically named Handler.ashx. I then pasted in the existing code from my earlier post, tweaked a few minor things, and had a working IHttpHandler in considerably less time than it's taken me to write this post. :)

    Here's what I ended up with in my Handler.ashx:

    <%@ WebHandler Language="C#" Class="Handler" %>
    
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Web;
    
    public class Handler : IHttpHandler
    {
    
        public void ProcessRequest(HttpContext context)
        {
            // Set the page's content type to JPEG files
            context.Response.ContentType = "image/jpeg";
    
            // Create integer variables.
            int height = 100;
            int width = 200;
    
            // ...
    
            // Create a bitmap and use it to create a
            // Graphics object.
            using (Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb))
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
    
                    // ...
    
                    g.Clear(Color.LightGray);
    
                    // ...
    
                }
    
                // Save the bitmap to the response stream and
                // convert it to JPEG format.
                bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg);
            }
        }
    
        public bool IsReusable
        {
            get
            {
                return true;
            }
        }
    }
    

    As you can see, the code is almost identical to the initial Page-based implementation! The only thing I think is worth calling out is that I've chosen to return "true" for the IsReusable property. The documentation for the IHttpHandler.IsReusable Property suggests that this property can be used to prevent concurrent use of the instance. Since our simple implementation doesn't make use of any global state, it should be safely reentrant, and therefore returns "true" to help ASP.NET avoid creating unnecessary instances of the class.

    There you have it: a simple change that gives us an implementation consuming fewer resources and consequently scaling better on a busy web server. Thanks for the great suggestion, Heath!!

  • Delay's Blog

    Start using using today! [A bit about the IDisposable interface and the using statement]

    • 2 Comments

    There's plenty to say about the IDisposable interface and the using statement, but you probably don't have time to read it all (and I don't have time to write it all!), so I'm going to try to keep this short and simple.

    First, let's make sure we're all on the same page. If you're not familiar with the relevant concepts, please take a moment to learn about .NET Garbage Collection, the IDisposable interface, the using statement, and the use of objects that implement IDisposable. (If you're a bibliophile, I understand that the book "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries" (ISBN 0321246756) contains additional material in section 10.3, "Dispose Pattern".)

    Now that we're all familiar with the concepts, I'd like to call attention to a few things:

    • Implementation of the IDisposable interface by the author of a class is optional and completely unnecessary for a correctly written class. Even without IDisposable, the Garbage Collector will eventually clean up all of the class's resources (possibly with the help of a Finalize method override).
    • However, without IDisposable, there is no way of controlling *when* a class's resources will be cleaned up. The Garbage Collector (GC) runs only when it needs to, so it could be seconds, minutes, or even hours after you're done using a class before the GC runs and cleans up those resources. Any resources held by that class (like file handles, sockets, SQL connections, etc.) will remain in use until that class is cleaned up by the GC. This can cause unexpected problems when, for example, the user has closed a file in an application, but the application continues holding on to that file and prevents the user from copying it, moving it, etc.. Worse still, such problems will occur "randomly" according to whether or not the GC has run.
    • So it's a good practice to call IDisposable.Dispose whenever you're done using a class that implements IDisposable so that its resources can be freed immediately and deterministically (i.e., predictably). As a side effect, this helps minimize the resource consumption of your application which always makes users happy.
    • However, simply adding a call to Dispose at the end of a block of code isn't a complete solution because it means that Dispose won't get called if an Exception is thrown anywhere within that block of code. If you're going to call Dispose, you want to *always* call Dispose, so you really want the call to Dispose to be within the finally block of a try-finally statement pair.
    • To address this, you can manually add a try-finally pair, *or* you can use the using statement which does so for you! Under the covers, the using statement maps to a try-finally pair which calls Dispose for the specified object within the finally block, but the beauty of the using statement is that it's a simpler, more concise way of doing so that keeps all the relevant code in one place and hides the gory details from view. You can even declare and initialize the object in the using statement itself! (See the documentation for using for examples.)

    With these points in mind, I propose following guidelines whenever dealing with an object that implements the IDisposable interface:

    • Always call the object's Dispose() method
    • Call Dispose() under all conditions (i.e., within a finally block)
    • Call Dispose() as soon as you're done with the object

    Conveniently, the using statement makes it easy to do *all* of these things! The using statement is a simple programming construct that's very readable and that helps your code perform reliably, predictably, and efficiently. It doesn't get much better than that, so if you aren't already, please start using using today!

  • Delay's Blog

    An image is worth a thousand HTML tags [How to: Display a custom image with an ASP.NET web page]

    • 4 Comments

    Imagine that you want to generate a custom image for your web site and that the content of the image will be dynamic enough that it's not possible to create the images beforehand. (One example might be an image of a clock displaying the current time.) It sure would be nice if you were able to create that image from an ASP.NET .aspx page whenever it was needed. But .aspx pages have to return HTML code, don't they? As it happens, they don't! While that's the job they perform most of the time, they can actually return any arbitrary data you'd like.

    In this case, we want figure out how to return an image. Like many things in life, it's pretty easy once you know where to look. Specifically, the MSDN documentation for the HttpResponse.OutputStream property is a great place to start. The example on that page shows how to generate a custom JPEG image and return it from an ASP.NET .aspx page. Click the "Copy Code" link, create a new ASP.NET web site in your favorite editor, replace the contents of Default.aspx with the sample code, and view it in your favorite browser. Problem solved! (Well, close enough - customizing that image is left as an exercise to the reader. :) )

    Digging a little deeper, we see that the sample code looks something like this:

    private void Page_Load(object sender, EventArgs e)
    {
        // Set the page's content type to JPEG files
        // and clear all response headers.
        Response.ContentType = "image/jpeg";
        Response.Clear();
    
        // Buffer response so that page is sent
        // after processing is complete.
        Response.BufferOutput = true;
    
        // ...
     
        // Create integer variables.
        int height = 100;
        int width = 200;
    
        // ...
    
        // Create a bitmap and use it to create a
        // Graphics object.
        Bitmap bmp = new Bitmap(
            width, height, PixelFormat.Format24bppRgb);
        Graphics g = Graphics.FromImage(bmp);
    
        // ...
    
        g.Clear(Color.LightGray);
        
        // ...
        
        // Save the bitmap to the response stream and
        // convert it to JPEG format.
        bmp.Save(Response.OutputStream, ImageFormat.Jpeg);
    
        // Release memory used by the Graphics object
        // and the bitmap.
        g.Dispose();
        bmp.Dispose();
    
        // Send the output to the client.
        Response.Flush();
    }
    

    Were I to use this code in a web page, I might change it to look a little more like this:

    private void Page_Load(object sender, EventArgs e)
    {
        // Set the page's content type to JPEG files
        // and clear all response headers.
        Response.ContentType = "image/jpeg";
        Response.Clear();
    
        // ...
     
        // Create integer variables.
        int height = 100;
        int width = 200;
    
        // ...
    
        // Create a bitmap and use it to create a
        // Graphics object.
        using (Bitmap bmp = new Bitmap(
            width, height, PixelFormat.Format24bppRgb))
        {
            using (Graphics g = Graphics.FromImage(bmp))
            {
    
                // ...
    
                g.Clear(Color.LightGray);
    
                // ...
    
            }
    
            // Save the bitmap to the response stream and
            // convert it to JPEG format.
            bmp.Save(Response.OutputStream, ImageFormat.Jpeg);
        }
    }
    

    Why? Well, I made three basic changes that I believe improve upon the original sample:

    1. I removed the use of HttpResponse.BufferOutput and HttpResponse.Flush. There seems to me to be no need to restrict the flow of data to the client in this case (on the contrary, let's allow it to start rendering the image as soon as possible). Unnecessary code is bad code, so it's gone.
    2. I converted the sample to take advantage of the using statement. You can read more about using in MSDN or wait for my next post in which I'll cover this handy statement in more detail.
    3. I dispose of the Graphics object as soon as it's no longer needed. Again, I'll cover the reasons for this in more detail in my post about the using statement.

    So there you have it: Custom image generation with ASP.NET. It's easy to do and it leverages all your existing knowledge about graphics under .NET!

  • Delay's Blog

    ASP.Newbie [Learning ASP.NET for fun and profit]

    My new group at Microsoft has me learning ASP.NET. While I'm no stranger to .NET (having coded in C# for a few years now), ASP.NET hasn't been something I've used before now. Sure, I've had a few ideas about simple web pages that seem like they could be handy, but I've never had the time (or web server) to play around with ASP.NET. Well, it looks like my time has come...

    The good news is that it's easier than ever to get started with ASP.NET. Start by downloading Visual Web Developer Express, a professional-grade development environment that's free for a year! (It even comes with a small, development-friendly web server that will save you from having to install IIS - nice touch!) Then surf on over to http://asp.net/ where you'll find a wealth of information about ASP.NET. Pay particular attention to the Tutorials which provide a great overview of ASP.NET. And while you're there, maybe you'll want to check out the technology preview of Atlas, an ASP.NET extension that's going to make AJAX applications simple to develop.

    Lots of good stuff. No money down. What are you waiting for??

  • Delay's Blog

    Why me? Why now?? [Introduction and technical background]

    • 1 Comments

    Truth be told, I'm still not sure how I feel about the use of blogs as a medium for technical discourse... But sometimes the best way to learn about something is to do it, so I'm starting my own blog and we'll see where it takes me. I'm going to try to stay focused on technology and coding and would like to post new content a few times each week. I'll definitely try to keep up with any comments that people are generous enough to post. Other than that, I have no particular agenda; topics will probably be drawn from my daily experiences and based on my areas of interest.

    My work experience at Microsoft: maintenance and development of the Windows CE Pocket Internet Explorer application (including the addition of JScript support and a DOM), some work on the Windows CE Terminal Server Client, considerable work on the cellular infrastructure for the Windows Mobile Smartphone and Pocket PC devices (including radio interfaces, SMS, and WAP), and quite a bit of work on the MSN Instant Messenger servers (including application development and manageability improvements).

    I've recently joined a new team here at Microsoft and am looking forward to playing with (and blogging about) many of the new technologies coming out of the Developer Division. I hope folks find this blog useful - I'll do what I can to keep it interesting!

Page 28 of 28 (277 items) «2425262728