Nate Talbert's profileShared MemoryBlogLists Tools Help

Nate Talbert

Occupation
Location

Shared Memory

Technical musings from the programming world
October 20

Very small programmatic WCF sample

Deployment time configuration is a much touted feature of Windows Communication Foundation (WCF), but for those who like to jump into the code, use intellisense, and prototype something, config is not really a great entry point.  I'll save that rant for another time.
 
Luckily, WCF put as much thought into the programming model as they did into the configuration model.  As such, it is very simple to get an app up and running which demonstrates the basics of WCF and lets you explore as you please.
 
Below is some code that I wish was shoved in my face the very first time I looked at WCF.
 
Simple Console App
namespace
ProgrammaticWCFSample
{
  using System;
  using System.ServiceModel;
 
  class Program
  {
    static void Main(string[] args)
    {
      // Service Code
      ServiceHost host = new ServiceHost(typeof(EchoService), new Uri("http://localhost/EchoService"));
      host.AddServiceEndpoint(
        typeof(IEcho).FullName,
        new BasicHttpBinding(),
        "http");
      host.Open();
 
      // Client code - move to another process/computer for a better demonstration
      IEcho echo = ChannelFactory<IEcho>.CreateChannel(
        new BasicHttpBinding(),
        new EndpointAddress("http://localhost/EchoService/http"));
      Console.WriteLine(echo.Echo("Hello World"));
    }
  }
 
  [ServiceContract]
  public interface IEcho
  {
    [OperationContract]
    string Echo(string toEcho);
  }
 
  public class EchoService : IEcho
  {
    public string Echo(string toEcho)
    {
      return "Echoing: " + toEcho;
    }
  }
}
October 19

VS 2005 freezes/hangs temporarily while saving

I've hit this issue and finding the solution wasn't as easy as it should have been.  As such I'm trying to get this out on the web in as many locations as possible.
 
My source:
 
And the original post:
 
The Problem:
VS 2005 starts taking 10-15 seconds to perform a save.
 
The Solution:
VS is looking for projects in remote locations and is timing out when trying to resolve the server.  The solution is to stop it from looking in those remote locations.  The recent projects list is populated using the following registry key:
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\ProjectMRUList
 
Delete any values which point to machines which cannot be accessed.  VS will start saving in a snappy manner all over again.
 
Thanks to Anderson for the original solution and to James Foster for reposting where I could find it.
October 18

Thoughts on Windows Vista

Last weekend I installed Windows Vista RC1 (Build 5600) on my laptop (Dell E1505, 1.66 GHz Intel Core Duo, 1 GB RAM, ATI Mobility Radeon X1300 w/ 256 MB Video RAM) and have been cruising along ever since.
 
High points:
  • Looks great.  Seriously, using an XP machine right now feels like going from HD cable back to standard definition.
  • Significant "no hang" improvement.  Remember when you would "repair" your network connection, hit cancel, and wait while it finished repairing anyway.  That's gone.  I also find that when a program does go into a "semi-hung" state it doesn't affect the system like it would in XP.  You can still move or minimize the window, it doesn't affect the ability of other windows to repaint, and the system as a whole is usable.
  • Zero app-compat problems so far.  Rhapsody just finished installing ...
  • Networking (especially wireless) works much better.
  • User Account Control popups are actually kind of nice.  I know that some find this statement to be blasphemy, but hear me out.  When I want to do an administrative task (install something, change power settings, modify drivers, etc) then there is one more click in my path.  This click is a last chance "are you sure" which I don't view as a bad thing.
    On the other hand, if some random program or web site is trying to do an administrative task then this is one more safeguard.  I guess what I'm trying to say is that as I'm working with my computer I know when to expect this popup and when not to expect it.  When it shows up in the first case I dismiss it quickly without thought, but when it shows up in the second scenario it actually gives me a chance to stop something potentially bad from happening.
  • Window previews are great.  Hovering over a tab on the task bar will give you a live miniture version of the window (yes, you'll see progress bars moving, etc).  Alt-Tab gives you the same preview.  And the rolodex style window switching is a cool looking feature - I have yet to find the scenario where I'd use it instead of Alt-Tab, but I will demo the hell out of that feature to everyone who will look.
Complaints:
  • I'm a developer and I've got Visual Studio 2005 installed on my machine.  When I'm prototyping I like to drop files to c:\ on occasion.  I like to do things that, in reality, should require administrative privileges.  There is a handy feature by which you can always start a program as Administrator (which I have set on VS 2005), but there is no option that turns off the User Account Control popup for just one program.  Every time I start VS as an admin this popup appears - unecessary.  I work with the program every day, I'm going to dismiss it every day, etc.  I wish there was a feature where I could turn off UAC for a single program.
  • I have a GemPlus Swap 433-SL smart card reader.  I had to fight with Vista to get the correct driver installed because the OS was CERTAIN that its smart card driver was better.  Its smart card driver didn't work.
  • My computer's monitor does not work correctly with sleep.  I don't know whether I should be mad at Vista or mad at Dell, but either way I have to hard reboot the system to get my display back.
More on User Account Control
I honestly thought that this would be the feature that made me stop using Vista, but I've actually come around to the other camp and view this as one of the features that makes me want Vista more.  90% of programs should not require administrative rights.  Outside of setup, why do you need to access the registry?  Why are you writing outside of the User (XP's Documents and Settings\<userName>) directory structure?
 
I guess my point is that the lack of UAC in earlier versions of Windows led to some crappy application design that utilized unnecessary permissions.  This doesn't make UAC a bad feature of Vista because it bothers you, but rather makes the old way of doing things seem archaic and unsafe.
 
As applications developed for Vista come out we will enter a world of safer computing where minimum privilege computing is the standard as opposed to the impossible.  Complaining about UAC seems counterproductive.  Instead, complain about the shoddy design of legacy apps.
 
Nate 

 

October 17

SerializationInfo.AssemblyName and TypeFullName

The ISerializable interface allows the programmer to hook into the serialization process utilitized by the BinaryFormatter.  This article describes how to serialize one object type as another type.
 
Why would you want to do that?
That is an interesting question.  The scenario that I recently encountered was one of forward compatibility.  In a previous version we needed to hook into serialization of a Hashtable field to reduce its size in some situations yet we were unable to update the newer versions of the code.  Since we couldn't update the newer code we couldn't just create a new type which implements ISerializable to do our work because the V2 code would be unable to deserialize that type.  We also didn't want to implement ISerializable (and take over serialization) for the entire class on which this Hashtable was a field - there were many other fields and we needed to making sure we didn't break our V2 code would have required a LOT of testing.
 
Now, if there were a way for us to serialize some new type as a Hashtable and only utilize our new type in the V1 code then we would be all set.  Well, that brings us back to this article.
 
Okay, I guess it has its place
When the BinaryFormatter approaches serializing an ISerializable object it does something like the following (NOTE: this is wild speculation based on observation and nothing else):
  • Create (or borrow) a SerializationInfo object
  • Set AssemblyName property equal to typeof(currentObject).Assembly.FullName
  • Set FullTypeName property equal to typeof(currentObject).FullName
  • Call ISerializable.GetObjectData
Now, when GetObjectData returns the BinaryFormatter does something like:
  • Write out header using AssemblyName and FullTypeName
  • Foreach name/object pair in Values write out the name followed by the serialization of the value
So, as you can see, in GetObjectData you can set SerializationInfo.AssemblyName and SerializationInfo.TypeFullName to whatever you like.  In my scenario above, I could create a custom Hashtable which serializes itself as a plain old Hashtable.  Code which only has access to the base Hashtable will still be able to deserialize my object.
 
It looks something like this:
[
Serializable]
public class CustomSerializationHashtable : Hashtable
{
  public override void GetObjectData(SerializationInfo info, StreamingContext context)
  {
    info.AssemblyName =
typeof(Hashtable).Assembly.FullName;
    info.FullTypeName =
typeof(Hashtable).FullName;
 
    Hashtable temp = new Hashtable();
    // process this such that the values to be serialized
    // are in the temp hashtable
 
    temp.GetObjectData(info, context);
  }
}
 
Completing the picture
Now, the question then becomes how to hook this CustomSerializationHashtable into my graph if every time I deserialize I'm just going to get back a plain old Hashtable.  The easiest way is to make use of IDeserializationCallback.  Let's say we started with the following class definition which we can change, but needs to remain forward compatible:
 
[
Serializable]
public class SerializationDemo
{
  private Hashtable data;
}
 
We can change it to the following:
 
[
Serializable]
public class SerializationDemo : IDeserializationCallback
{
  private Hashtable data;
 
  void IDeserializationCallback.OnDeserialization(object sender)
  {
    if (data != null)
    {
      data = new CustomSerializationHashtable(data);
    }
  }
}
 
Now, every time we deserialize we will take our base Hashtable, wrap it in our custom Hashtable, and be happy as a clam.  When we serialize the CustomSerializationHashtable will tell the formatter to write it out as a base Hashtable and save some compressed version of itself.
 
Caveats
  • Is this the most efficient way to reduce the size of something you are serializing?
    • Probably not.  It is almost always faster to maintain your "compressed" list at runtime then to iterate over some larger list at serialization time.  But, some scenarios lock you into serialization time compression like this so this is a handy pattern to know.
  • Can I do this with objects that don't implement ISerializable?
    • Not easily.  Let's say you want to serialize some class Foo as a string.  You would have to understand how string stores its values so that you could mimic that in your GetObjectData.  The nice thing about ISerializable types when using this pattern is that you just call GetObjectData on the actual type you are trying to serialize after doing your processing. 
  • What about sealed classes?
    • This requires a completely different approach.  The reason is that when you can derive from the type you are impersonating you can just insert your derived type in their place in the graph.  Using our example, we just put a CustomSerializationHashtable in place of our normal Hashtable.  Now, when SerializationDemo gets serialized it will add an entry with name "data" and with the value we give it.
      If Hashtable had been sealed then we couldn't have hooked into the graph in the right location.  We couldn't have tricked SerializationDemo into serializing our custom object as the value for the key "data" in its serialized form.
So is this just useless trivia?
Possibly.  You might code your entire life and never find a use for this.  But, on the off chance you do need this, it's now out here in Shared Memory.
 
Nate
 
October 15

Choosing a name is difficult ...

I had the most attrocious time picking a suitable name for this blog.  I wanted something unique, I wanted something humorous, I wanted something appropriate, and I wanted something cool; I finally gave up on all of that and went with Shared Memory.
 
About the author
My name is Nathan Talbert and I'm a software design engineer with Microsoft.  My current programming interests lie in Windows Workflow Foundation and Windows Communication Foundation (both parts of .NET 3.0 - http://www.netfx3.com/).  When I'm not at work I enjoy long walks on the beach, candlelight dinners ...
 
About this blog
I come across a lot of neat stuff at work.  At least I think its neat.  This blog is a way for me to get those little tidbits out into the public in an attempt to be noble and help forward the communal knowledge on which we all rely.  This is also a public forum for me to say random things, complain from time to time, and apologize to the masses when I've been bad.  Enjoy!