Scott Hanselman

The Computer Back - Pain and the Programmer

July 19, '04 Comments [31] Posted in Programming
Sponsored By

I'm on my butt today.  More specifically, on my back.  This weekend my lower back seized up - just one muscle it seems, as the back turns into butt.  It's amazing how a little stabilizer muscle can go nuts suddenly and mess up your whole system. 

I call it "Programmer Back" as there are a handful of other folks that sit in front of a machine all day that have had this problem. 

It seems the symptoms are nearly universal:

  • Everything is fine, often for months.
  • A seizing happens and you drop to your knees.
  • Often you can't stand without help, or if you do, you're bent over like an old person.
  • If you don't move, you're OK, but bending over, or rolling out of the bed become impossible.
  • It lasts for as little as 3 days or a much as a week and a half.

Some say ice, some say heat, some say massage.  Still others advocate chiropractic.

Have you had Programmers Back?  How do you deal with it?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Validating that XmlSchemas and their Imports are Valid and All Good with an XmlResolver.

July 15, '04 Comments [1] Posted in XML | Bugs
Sponsored By

The very awesome Oleg Tkachenko commented in a recent post of mine (as did Patrick Cauldwell, in person) that what I was doing could have been accomplished with a custom XmlResolver.  Both are absolutely right.

I did my little hack because it was quick but Oleg's right, it would have been "more correct" to do something like this:

public class XmlCustomResolver : XmlUrlResolver
{
  override public object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
  {
     //Here, mess with absoluteUri.AbsolutePath and return an XPathNavigator or Stream or whatever
 
}
}

So what happens is that you pass in the Resolver into the call to .Compile like:

foreach(XmlSchema x in w.Schemas)
{
  
x.Compile(new ValidationEventHandler(OnValidationEvent), new XmlBaseDirectoryResolver());
}

However, my problem was a smidge more subtle than it initially appeared.

The problem was, for me, that I want to resolve the schemaLocations (which look like "banking/someDomainObject.xsd") relative to the path that the WSDL is in, like "C:\dev\whatever\wsdl\".  However, by the time we get into the Resolver (when .Compile calls back to GetEntity()) the propery absoluteUrl.AbsolutePath already contains "C:\dev\MyTestConsole\bin\debug\someDomain\banking\someDomainObject.xsd."  See?  It's already "pre-resolved" the path relative to AppDomain.CurrentDomain.CurrentDirectory

At this point, I have no way (that I can see) to know what was the original relative path.  I want the schemaLocation to be "C:\dev\whatever\wsdl\banking\someDomainObject.xsd."  I could have passed the directory of the WSDL file into the constructor call to the Resolver.  So we add:

foreach(XmlSchema x in w.Schemas)
{
   x.Compile(new ValidationEventHandler(OnValidationEvent), new XmlBaseDirectoryResolver(wsdlFile.DirectoryName));
}

Note that the AbsolutePath has the Directory Separators as "/", so I have to fix those as well.  Here's the final "XmlBaseDirectoryResolver."  It's more lines of code, but it's also reusable.

public class XmlBaseDirectoryResolver : XmlUrlResolver
{
 
private string baseDir = String.Empty;
  public XmlBaseDirectoryResolver(string baseDirectory) : base()
 
{
   
baseDir = baseDirectory;
 
}

 
override public object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
 
{
   
if (absoluteUri.IsFile == true)
    
{
      
//Change the directory characters to the same ones that AppDomain.CurrentDomain.BaseDirectory uses
      
string newFileName = absoluteUri.AbsolutePath.Replace('/',Path.DirectorySeparatorChar);
      
//Now, yank the automatically added portion...
      
newFileName = newFileName.Replace(AppDomain.CurrentDomain.BaseDirectory,String.Empty);
      
//Add our Base Directory...
      
newFileName = Path.Combine(baseDir, newFileName);
      
//Return the file...
      
return new FileStream(newFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
    }
    return base.GetEntity(absoluteUri, role, ofObjectToReturn);
  }
}

The big problem with this particular result?  It doesn't work with relative paths that use the dotdotslash "../../whatever/this.xsd."  At this point - the point of resolution - too much has been already resolved for me. :)  The only way I could fix that would be to work backwards to figure out how many ../..'s were removed for me, and put them back.  Not worth it.

Oleg has a great article up on his blog on how to Create your Own XmlResolver.  His actually retrieves the schema (stored) in a SQL Server. 

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Using the Server (rather than Workstation) Garbage Collector with the .NET Framework (CLR)

July 15, '04 Comments [2] Posted in ASP.NET | XML | Tools
Sponsored By

We run a big .NET Application Server, often on multi-proc machines, so we care about performance and, consequently, garbage collection.  I've collected a few resources around the two kinds of Garbage Collectors available in .NET, the Workstation GC and the Server GC.

From the MSDN Help:

Two different Garbage Collectors are available for the CLR: a Workstation GC and a Server GC. Console and Windows Forms applications host the Workstation GC, and ASP.NET hosts the Server GC. The Server GC is optimized for throughput and multi-processor scalability. The server GC pauses all threads running managed code for the entire duration of a collection, including both the Mark and Sweep Phases, and GC happens in parallel on all CPU's available to the process on dedicated high-priority CPU-affinitized threads. If threads are running native code during a GC then those threads are paused only when the native call returns. If you are building a server application that is going to run on multiprocessor machines then it is highly recommended that you use the Server GC. If your application in not hosted by ASP.NET, then you are going to have to write a native application that explicitly hosts the CLR.

HINT:   If you are building scalable server applications, host the Server GC. See Implement a Custom Common Language Runtime Host for Your Managed App.
  • Hosting the CLR in a generic service and Hosting the Server GC: "To load the svr GC, we created a generic Windows service that loads the svr GC, creates an AppDomain, and runs our application."
     CComPtr spRuntimeHost;
     HRESULT hr = CorBindToRuntimeEx(NULL, 
       //Retrieve latest version by default
      L"svr",
     
       //Request a Server (svr) or WorkStation (wks) build of the CLR
      STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN, 
      CLSID_CorRuntimeHost,
      IID_ICorRuntimeHost,
      (void**)&spRuntimeHost);
  • Using the Server Garbage Collector:  
    1. Create the system environment variable COMPLUS_BUILDFLAVOR to SVR
    2. SET COMPLUS_BUILDFLAVOR = SVR
    3. Generate this key in the windows registry: HKLM/Software/Microsoft/COMPlus with a single string value BuildFlavor with value "svr"
    SDH Note: This is fully unsupported my Microsoft.
  • Improvements in .NET 1.0 SP3 and .NET 1.1 SP1 and How to enable CLR Server GC?
     <Configuration>
        <runtime>
            <gcServer enabled=“true“ />
        </runtime>
    </Configuration> 

From Chris Kinsman: Here’s a way to do it that’s not a hack – right-click on My Computer in .NET Configuration in Administrative Tools. UPDATE: In fact, this is NOT so, details on this setting at OdeToCode.com

 

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Validating XML schemas that have been xs:imported and have schemaLocation

July 12, '04 Comments [4] Posted in Web Services | XML
Sponsored By

In this example, Wsdl is a class that's one of our internal convenience wrappers around System.Web.Services.Description.ServiceDescription.  The Schemas property is just the XmlSchema[] that from service.Types.Schemas. 

I wasn't sure if my WSDL file was kosher, and I wanted to "validate" the whole setup.  Most of my XML Schemas were pulled in via xsd:import in my wsdl like:

 <wsdl:types>
  <xsd:schema targetNamespace="
http://www.corillian.com/thingie/operations/2199/05" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsd1="http://www.corillian.com/thingie/operations/2199/05"> <!-- bogus namespaces for example -->
   <xsd:import namespace="
http://www.corillian.com/thingie/banking/domain/2199/05" schemaLocation="..\banking\BankingDomain.xsd"/>
  </xsd:schema>  
 </wsdl:types>

...and as you can see, the schemaLocation was relative.  The way I was going to force a Validation of the XML Schemas (other than physically loading each of them into memory myself) was to call .Compile().  However, it appears that the relative paths were being resolved relative to the Current AppDomain's current directory, NOT the directory the WSDL was located in!  So:

Wsdl w = new Wsdl();
w.Load(file.FullName);
foreach(XmlSchema x in w.Schemas)
{
  foreach(XmlSchemaImport i in x.Includes)
  {
    
i.SchemaLocation = Path.Combine(file.DirectoryName,i.SchemaLocation);
  
}
  x.Compile(new ValidationEventHandler(OnValidationEvent), new XmlUrlResolver());
}

Before I mess with the WSDL and Schemas, I take the directory that the WSDL file was located in and use it as a base directory for the relative schemaLocation.  Thank goodness the SchemaLocation property was not readonly! :)  Using Path.Combine has the added benefit of collapsing ".." relative paths.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Obscure Off-Topic Tip of the Day - How to Get Windows Explorer File Copy/Move to "Yes to All" or "No to All"

July 10, '04 Comments [2] Posted in Musings
Sponsored By

Thanks to John Elliot, how to get Windows Explorer to "Yes to All" or "No to All":

If you are copying manually in the GUI with a drag and drop or a
CTRL+C/CTRL+V then press SHIFT when you click 'Yes/No' the first time you are prompted and it will remember that as the default answer for all other files in the copy operation.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.