views:

49

answers:

0

My question is about the temporary files that are generated by the .NET framework in support of XmlSerialization.

Here is the background prompting me to ask the question.

The software that I have deployed is deployed in 4 environments all of them windows 2003 servers.

The .net runtimes on all 4 environments are the same service packs. The user permissions in all environments for the C:\windows\temp directory are all assigned to allow NETWORK SERVICE and ASPNET users on those machines full access.

The software components consist of the following (the components have been separated as part of a preexisting design):

  1. .NET 1.1 Web Application - (web application 1).
  2. .NET 1.1 Web Service Application - (web service 2)
  3. .NET 1.1 windows service - (windows service 3)
  4. .NET 2.0 Application - (web application 4)

Each web and web service application has been allocated a different application pool in IIS.

Web service 2 is used by the other components listed above. Web application 1, Windows Service 3 both have the same .net1.1 dll client to web service 2. Web application 4 has a .net2.0 version of the client for web service 2.

The client dll containing the web service bindings has the same "namespace" accross all applications. The server dll defining the web service bindings inside web service 2 also has the same namespace.

The .NET 2.0 web application has been configured to use a different temporary directory path when generating files by specifying it in the web.config file:

<xmlSerializer tempFilesLocation="c:\newTemp"/>

In one environment only I am seeing the following error intermittently:

Unable to generate a temporary class (result=1). error CS1567: Error generating Win32 resource: The process cannot access the file because it is being used by another process.

Stack =    at System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, CompilerParameters parameters, Evidence evidence)
   at System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, CompilerParameters parameters, Assembly assembly, Hashtable assemblies)
   at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
   at System.Xml.Serialization.XmlSerializer.FromMappings(XmlMapping[] mappings, Type type)
   at System.Web.Services.Protocols.SoapClientType..ctor(Type type)
   at System.Web.Services.Protocols.SoapHttpClientProtocol..ctor()
   at Microsoft.Web.Services2.WebServicesClientProtocol..ctor()

This error is not occuring in the other 3 environments.

And the software is exactly the same version (except for the parts dynamically generated by the .net framework) in each environment.

The other 3 environments have gone through rigorous testing spanning about 3 months of activity. The 4th environment is a new server build.

A fileaudit of the software components I am installing verifies that they are the same versions as the other 3 environments. (I have more control over the software components than I do the environment, and am reliant on a third party for environmental support).

The only other difference I can think of with this new server is that it's probably a different hardware build, but the operating system is the same.

On the server that has these symptoms, the error usually occurs if I reset the app pool, if I am lucky, it is elusive to recreate. And it can occur on different transactions to the web service.

I was lucky enough to capture it using procmon. This showed that 2 different w3wp processes were attempting to access the same temporary .cs file that was located in C:\windows\temp\ resulting in a "SHARING VIOLATION" in on of the processes causing it to fail compilation. The PIDs of the 2 processes showed that both processes belonged to separate Application pools.

Both of those application pools were running the .NET 1.1 applications.

The error is not occuring at all in the .NET 2.0 application.

And has not been seen in the .net1.1 applications until they were installed on this new server.

I had attempted using different user identities for each app pool, assigning each of them different logons and specifying these in the app pool settings in IIS, in the hope that they would use different temp directories. However they still all ended up using C:\windows\temp and the same error still occurs intermittently.

The server is not running any antivirus software and I have disabled the windows indexing service, (I have read that issues like this have been caused by other processes temporarily locking the generated files).

Currently because of the new configuration property available in .NET 2.0 I am intending to recompile the applications in .NET 2.0 and assigning each of them a separate temp directory path to use for dynamic serialization (or use sgen).

My questions are as follows:

Has this error happened to anyone else? (or am I just going mad)

Does the observation that the 2 processes are attempting to use the same temporary file names in support of the xml serialization seem correct? (It's conclusion I've come up with, not sure if its sane but its the current interpretation I have drawn from the procmon results).

How is the temporary file name generated? Is it somehow derived from the type and namespace and assembly of the dll containing the serializable types or is it entirely unrelated?

How can I get the XmlSerializer to use a different temp directory in .NET 1.1 (I know this can be done in .NET 2.0)? Can this be done somehow with environment variables? (my attempt at using separate user accounts in the hope they would use their own temp folders in their user directories failed).

Is it possible to precompile XmlSerializer in .NET 1.1? (I know .NET 2.0 supports this, maybe there is some manual way of achieving this for .NET 1.1 soap clients?).

Is compiling the .NET 1.1 applications as .NET 2.0 the only option available?

(its the next step I'm going to take since I know it will resolve the error, but it would be interesting to see other possibilities).