Bill Blogs in C#

Bill Wagner discusses C#, LINQ, and other items of interest

May 2005 - Posts

How to push configuration information out to client computers...

A question:

In Item 37 (Use the Standard Configuration Mechanism) you describe the SpecialFolder.CommonApplicationData parameter to GetFolderPath.

When I read this I thought that you were saying that the file would be copied to all machines in my company (rather like user profiles are copied to a machine at login time). This would be great! But I couldn't find more information about it.

Have I got completely the wrong idea?

Answer:

The purpose of storing application information in the best location is to ensure that you support both multiple users on the machine and users with roaming profiles.

The CommonApplicationData folder is where you store data that should be shared by all users of your application on a single machine. The ApplicationData folder is a per-user setting. It is under a single user’s home tree, and can be modified by roaming profiles. When roaming profiles are created, users will have their home data directories assigned to a network share. Your application will automatically pick up the user’s data from the right location on the network. Of course, the LocalApplicationData folder stores per user data for a particular machine.

Unfortunately, none of this will push a configuration file out to every machine on the network. For that kind of action you’ll need some other mechanism. The practices I discussed in Item 37 make it easier to use that data once it’s pushed out to your users. And, the roaming profiles means that you might be able to push less information to each desktop.

Your original question only hinted at the functionality you are trying to achieve. There are no touch deployment libraries available for .NET 1.1. .NET 2.0 adds integrated support in VS.NET, and additional deployment scenarios. Those may address the probles your are encountering.



Posted by wwagner | with no comments
Filed under:
A reader asks about a variation of loop variable hoisting

Question on Item 11.

Regarding your examples of loops, where would the following end up in efficiency?

// Loop 4: (

for ( int index = 0, len = foo.Length;  index < len; index++)

This is how I used to do it in Java (I wonder if I didn’t actually learn it from “Effective Java”). Now I use foreach, but am still interested in your insight on which of loop 2 or 3 this resembles and how efficient it is.

Answer:

The core point of Item 11 is not that one particular looping construct is so much faster than any other. Rather, it is that the performance differences between different constructs are just not that large. You should instead pick the construct that creates the most readable and most maintainable code. Following on that advice, the product teams are working on optimizing the most readable constructs, rather than less common and less readable constructs.

My own tests on your construct bear that out. The version you have exhibits the same performance penalty that I mentioned in Item 11 of Effective C# regarding loop variable hoisting. My timings showed this to be the slowest of the looping constructs I mentioned there.

The moral of the story is this: Write the clearest code you can, and optimize these low-level constructs only after running performance tests.



Effective C# Errata page
Those mistakes readers have found
Effective C# Homepage
Learn more about the book
Posted by wwagner | with no comments
Filed under: ,
SRT Solutions is looking for two subcontractors
The full description is at the link below.  These two developers would be reporting to me on my current project.

The job offer
More about the position
Posted by wwagner | with no comments
Filed under:
Josh Holmes and I are both speaking on the Smart Client Track.

We (SRT Solutions) have two principals speaking at Visual Studio 2005 Dev Con in Detroit. Josh Holmes is giving the talk on Smart Client Development on Mobile Devices. I’m giving the talk on Deploying Smart Clients with ClickOnce. I’ve been excited about lowering the cost of deploying client applications for some time. (See the articles in the link section of this post). The article below show techniques you can use with Visual Studio 2003.  At VS 2005 DevCon, it's all about VS 2005.

So, what are you waiting for? Sign up for VS 2005 Dev Con. The free giveaways alone are worth the price of admission.



The VS 2005 Dev Con Registration Page
How you can learn about the event and sign up
VS 2005 Dev Con Detroit
The Detroit Agenda
ServerSide.NET Using the App Updater Block
The first way to update smart clients
ServerSide.NET: Run From the Web
Nothing could be simpler
ServerSide.NET: Updater Application Block
Yet another way to update applications

Posted by wwagner | with no comments
Or, a reasonably simple technique to build polymorphic web services.

I participated in a discussion recently about how to build a web method that can accept and return multiple schemas.

I’d like to build this web service API:

[WebMethod]
Response ProcessRequest( Request packet )
{

  // elided.

}

With a little help from Xml attributes in .NET, this is possible. It’s not quite as elegant as I’d like (yet) but it still saves time and is quite resistant to breaking changes at the server.

Start by defining the abstract Request and Response classes:

public abstract class Request
{

  public abstract Response ProcessMe();
}


public abstract class Response
{

}

Now you can fill in the rest of your web method body:

[WebMethod]
public Response ProcessRequest( Request packet )
{

  return packet.ProcessMe();
}

Your web service implementation is done. Following the example from OO, you simply create new classes derived from Request and Response. Here are two small examples. (You can download the full code from the link below. The snippets are illustrative, and not meant to be the full implementation.)

This pair returns the sum of two numbers:

public class AddRequest : Request
{

  public AddRequest()
  {

  }


  private int left;
  public int Left
  {
    // ...

  }


  private int right;
  public int Right
  {

    // ...

  }


  public override Response ProcessMe()
  {

    return new AddResponse( Left, Right );
  }

}


public class AddResponse : Response
{

  public AddResponse()
  {

  }


  public AddResponse( int left, int right )
  {

    Result = left + right;

  }


  private int result;
  public int Result
  {

    // ...

  }

}

And, just to show you can do this with any multiple types of requests, here’s an example where the request has no parameters. It returns the current time:

public class TimeRequest : Request
{

  public TimeRequest()
  {

  }


  public override Response ProcessMe()
  {

    return new TimeResponse();
  }

}


public class TimeResponse : Response
{

  public TimeResponse()
  {

    ThisTime = DateTime.Now;

  }


  private DateTime thisTime;
  public DateTime ThisTime
  {

    // ...

  }

}

Now comes the part that is a little less than elegant. What I’ve done so far does not work as a web service. The XmlSerializer does not know how to serialize the derived classes (TimeResponse and AddResponse) from the server. In addition, the generated WSDL document will not contain the definition for any of the derived request or response types. (For those of you with a C++ background, this problem is analogous to slicing objects when you passed types by value.) You can fix that by adding attributes on the Request and Response classes to note what derived types should be included in the serialization schema:

[ XmlInclude( typeof( AddResponse ) ) ]
[ XmlInclude(
typeof( TimeResponse ) )
public abstract class Response

[ XmlInclude(
typeof( AddRequest ) ) ]
[ XmlInclude(
typeof( TimeRequest ) ) ]
public abstract class Request

Finally, you need to add an XmlElement attribute to the web method:

[WebMethod]
[
return: XmlElement("Response")]
public Response DoRequest( Request r )

Anytime you add a new message, you do a few small steps:

Create your new request schema, by deriving a class from Request.

Create your new response schema, by deriving a class from Response.

Add XmlInclude attributes for the two new schemas on the Request and Response type definitions.

Final note: Josh Holmes, one of my business partners is one of the best people around on XML schemas. He’s going respond to this post within a week, expanding on the sample to serialize more complicated objects, including collections.



The full sample
Download and play with it yourself
Josh's blog
Look here for the followup
Rockford Lhotka comments
After my original post, Rockford Lhotka added his thoughts
Posted by wwagner | with no comments
Filed under: ,
Or why I'm reading fewer blogs and opening the books on my shelf.

I’ve spent the last two weeks reviewing portions of a book manuscript for Addison-Wesley. It’s been great fun, and an eye-opening experience. I’ll post commentary about the specific title when it’s closer to publication. It’s a great manuscript, and I’ll be recommending it to every tech person I know. These comments are general thoughts about how we find and consume information.

Like many other technical people, I’ve subscribed to numerous blogs. It’s a great way to stay current with the thoughts and ideas of some of our brightest peers. In particular, Brad Abrams, Rico Mariani, and Krzysztof Cwalina are must reads for anyone doing .NET development. If you’re interested in C#, Dan Fernandez, Scott Wiltamuth and Jay Bazuzi are on the must-read list. There are other of course (I’m subscribed to over 200 feeds), but those are the cream of the crop.

There is much to like about using blogs as a means of communication. It’s immediate. It’s convenient. There is very little friction for both the person posting to the blog, and those reading the blog.

But, I worry that we are all shifting our focus a bit too much. I learned more in the evenings spent reading a draft manuscript (roughly 150 pages) than I have over the last several months reading blogs. I think there are several reasons for this. The first is depth of coverage. I’ve never seen anyone go into the detail of a book chapter (or even shorter excerpt) in a blog. It doesn’t seem natural to blog for 20 pages or more on a single subject. And yet, some subjects require that kind of detail. At least, they do if you want to cover them with any hope of completeness.

Second, and far more important, is the editorial process. Here I’m speaking both as an author and a tech reviewer. If a book is published by one of the major publishers, at least 12 pairs of eyes have read it before it goes to print. Equally important, those reviewers are in two groups: People that understand the subject matter (almost) as well as the author and are likely to find any technical errors, and people in the target audience for the manuscript who are likely to find any explanations that are vague or misleading. Like everything else, some human error will escape everyone’s attention. But still, the quality of the prose, the explanations, and the example code is always much higher after that much review and examination. Think about it: you probably found typos, unclear phrasing, and more reading your blogroll today.

Third, there are times when the signal to noise ratio just isn’t high enough. Being very blunt about it, I really don’t care if you saw The Hitchhiker’s Guide to the Galaxy last weekend. If your blog is supposed to be about technical information, I’m reading it for technical content, not your social calendar.

So that leaves me with some action items for myself, and some recommendations for you. I’m going to trim my blog list way down. I hope to have under 50 by the end of the week. That will free up time for other information sources. I’ve got a stack of books that I’ve been trying to make time for, and my last tech review gave me the whack in the side of the head I needed to make time for it.

By the way, when you trim your own blog roll, please keep reading mine.



Posted by wwagner | with no comments
Filed under: