Artigo: 872800 - Última revisão: sexta-feira, 18 de Maio de 2007 - Revisão: 3.4

CORRECÇÃO: assistir clientes Web gerar assemblagens de seriação sempre que a aplicação seja executada

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Reduzir tudo

Sintomas

Uma aplicação que chama um serviço Web pode demorar mais tempo do que o esperado para fazer a primeira chamada quando comparado com as chamadas subsequentes. Este atraso ocorre sempre que executar a aplicação.

NOTA esta correcção não é possível aplicar existente num sistema que executa o Microsoft.NET Framework 1.1 Service Pack 1. Se tiver instalado o.NET Framework 1.1 Service Pack 1 e estão a ter o sintoma descrito no artigo, pedir o pacote de agregação da correcção descrito no artigo da Base de Dados de Conhecimento da Microsoft 890673 para obter uma resolução. Para obter mais informações, clique no número de artigo que se segue para visualizar o artigo na base de dados de conhecimento da Microsoft (KB, Microsoft Knowledge Base)::
890673  (http://support.microsoft.com/kb/890673/ ) Disponibilidade de serviços Pack Post-Service 1.1.NET Framework Web XML 1 e agregação pacote 8 da correcção de Mensagens XML

Causa

O atraso ocorre quando executa uma aplicação do cliente pela primeira vez uma vez que o proxy de serviço Web utiliza uma assemblagem de serialização, e a assemblagem da seriação é compilada dinamicamente durante a execução. A assemblagem da seriação serializes e deserializes as informações de acordo com para o pedido do cliente e os resultados do servidor que são devolvidos para o pedido. A Hora adicional na primeira chamada ocorre devido a compilação da assemblagem a serialização.

Resolução

Esta correcção também tem de ser instalada nos computadores que executam as aplicações que utilizam as assemblagens pregenerated. Para resolver este problema, siga estes passos::
  1. Obter e em seguida, instale a correcção. Para efectuar este procedimento, siga estes passos.:
    1. Obter a correcção do pacote de correcções que se segue:
      890673  (http://support.microsoft.com/kb/890673/ ) Disponibilidade de serviços Pack Post-Service 1.1.NET Framework Web XML 1 e agregação pacote 8 da correcção de Mensagens XML
    2. Extrair a correcção para uma pasta.
    3. Clique duas vezes a correcção para instalar a correcção no seu computador.
  2. Pregenerate a assemblagem serializador. Segue-se de exemplo numa aplicação de consola que irá gerar as assemblagens serializador para uma assemblagem proxy mínima,. Para obter uma versão mais sofisticada desta aplicação, consulte a secção " Mais informações ". Para criar o pregenerator serializador simples, siga estes passos:
    1. Criar uma nova aplicação de consola Microsoft Visual C#.NET com o nome PreGen.
    2. Mude o nome do ficheiro Class1.cs para Pregen.cs.
    3. Substituir todo o código existente no ficheiro PreGen.cs pelo código que se segue.
      namespace PreGenNS {
          using System;
          using System.Collections;
          using System.IO;
          using System.Reflection;
          using System.Xml.Serialization;
          using System.Text;
          using System.Globalization;
          using System.Web.Services.Protocols;
          using System.Threading;
          using System.CodeDom.Compiler;
          
          public class Pregen {
              public static int Main(string[] args) {
                  if (args.Length != 1) {
                      Console.WriteLine("usage: ");
                      Console.WriteLine("  pregen assembly");
                      return 1;
                  }
                  Pregen pregen = new Pregen();
                  return pregen.Run(args[0]);
              }
      
              int Run(string assemblyName) {
                  
                  try {
                      GenerateAssembly(assemblyName);
                  }
                  catch (Exception e) {
                      if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                          throw;
                      }
                      Error(e, "Error: ");
                      return 1;
                  }
                  return 0;
              }
      
              void GenerateAssembly(string assemblyName) {
                  Assembly assembly = LoadAssembly(assemblyName, true);
                  Type[] types = assembly.GetTypes();
                  ArrayList mappings = new ArrayList();
                  ArrayList importedTypes = new ArrayList();
                  XmlReflectionImporter importer = new XmlReflectionImporter();
                  for (int i = 0; i < types.Length; i++) {
                      Type type = types[i];
                      if (HttpWebClientProtocol.GenerateXmlMappings(type, mappings)) {
                          importedTypes.Add(type);
                      }
                  }
                  if (importedTypes.Count > 0) {
                      Type[] serializableTypes = (Type[])importedTypes.ToArray(typeof(Type));
                      XmlMapping[] allMappings = (XmlMapping[])mappings.ToArray(typeof(XmlMapping));
                      
                      bool gac = assembly.GlobalAssemblyCache;
                      string codePath = gac ? Environment.CurrentDirectory : Path.GetDirectoryName(assembly.Location);
                      string serializerName = assembly.GetName().Name + ".XmlSerializers" ;
                      string location = Path.Combine(codePath, serializerName + ".dll");
      
                      CompilerParameters parameters = new CompilerParameters();
                      parameters.TempFiles = new TempFileCollection(codePath);
                      parameters.GenerateInMemory = false;
                      parameters.IncludeDebugInformation = false;
                      parameters.TempFiles = new TempFileCollection(codePath, true);
                      Assembly serializer = XmlSerializer.GenerateSerializer(serializableTypes, allMappings, parameters);
                      if (serializer == null) {
                          Console.Out.WriteLine("Failed pregenerate serializer for '{0}'", assembly.Location);
                      }
                      else {
                          AssemblyName name = serializer.GetName();
                          Console.Out.WriteLine("Serialization Assembly Name: {0}", name.ToString());
                          Console.Out.WriteLine("Generated serialization assembly for assembly {0} --> '{1}'.", assembly.Location, location);
                      }
                  }
                  else {
                      Console.Out.WriteLine("Assembly '{0}' does not contain any serializable types.", assembly.Location);
                  }
              }
      
              static Assembly LoadAssembly(string assemblyName, bool throwOnFail) {
                  Assembly assembly = null;
                  string path = Path.GetFullPath(assemblyName).ToLower(CultureInfo.InvariantCulture);
                  if (File.Exists(path)) {
                      assembly = Assembly.LoadFrom(path);
                  }
                  else {
                      try {
                          assembly = Assembly.Load(assemblyName);
                      }
                      catch (Exception e) {
                          if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                              throw;
                          }
                          Error(e, "Error: ");
                      }
                      if (assembly == null) {
                          string justName = Path.GetFileNameWithoutExtension(assemblyName);
                          try {
                              assembly = Assembly.Load(justName);
                          }
                          catch (Exception e) {
                              if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                                  throw;
                              }
                              Error(e, "Error: ");
                          }
                      }
                  }
                  if (assembly == null) {
                      if (throwOnFail)
                          throw new InvalidOperationException("Cannot load assembly " + assemblyName);
                      return null;
                  }
                  return assembly;
              }
      
              static void Error(Exception e, string prefix) {
                  Console.Error.WriteLine(prefix + e.Message);
                  if (e.InnerException != null) {
                      Error(e.InnerException, "  - ");
                  }
              }
      
              static void Warning(Exception e) {
                  Console.Out.WriteLine("  - " + e.Message);
                  if (e.InnerException != null) {
                      Warning(e.InnerException);
                  }
              }
          }
      }
      
    4. Adicione uma referência ao ficheiro System.Web.Services.dll.
    5. Criar o projecto.
    6. Copie o ficheiro PreGen.exe para a pasta que contém a assemblagem que tenha o código de proxy. Por exemplo, copie o ficheiro PreGen.exe à assemblagem que contém o código do cliente de serviço Web.
    7. Pregenerate os serializers para o serviço Web utilizando o ficheiro PreGen.exe preparado. Por exemplo, se o código de proxy for no ficheiro WindowsApplication1.exe, execute o seguinte comando na linha de comandos:

      PreGen.exe WindowsApplication1.exe

      NOTA um ficheiro.dll é gerado na mesma pasta em que a assemblagem de cliente é guardada, assim que executar o comando no passo g.
    8. Abra o código do cliente no Microsoft.NET IDE do Visual Studio.
    9. No Explorador solução, expanda o nó Web Reference . Por exemplo, se tiver adicionado uma referência a service1 utilizando localhost, expanda localhost .
    10. Expandir Reference.MAP , e seguida, faça duplo clique no ficheiro Reference.cs.
    11. Localize o seguinte código:.
          [System.Diagnostics.DebuggerStepThroughAttribute()]
          [System.ComponentModel.DesignerCategoryAttribute("code")]
          [System.Web.Services.WebServiceBindingAttribute(Name="Service1Soap", Namespace="http://tempuri.org/")]
    12. Substituir o código no passo k com o seguinte código.
      [System.Diagnostics.DebuggerStepThroughAttribute()]
      [System.ComponentModel.DesignerCategoryAttribute("code")]
      [System.Web.Services.WebServiceBindingAttribute(Name="Service1Soap", Namespace="http://tempuri.org/")]
      [System.Xml.Serialization.XmlSerializerAssemblyAttribute(CodeBase="< Nome DLL >")]
      
    13. Reconstruir o Cliente de serviços Web.

      NOTA tem reconstruir o cliente por causa do atributo. O cliente tem uma dependência run-time na assemblagem que contém os serializers MySerializers.dll. Assim, deve implementar esta assemblagem com a aplicação e disponibilizar a assemblagem na localização onde o cliente é carregado.

Mais Informação

Vinculação de assemblagem

O tipo do argumento que fornecer ao atributo XmlSerializerAssemblyAttribute determina a forma como a assemblagem serializador está carregada. Se o argumento codebase for utilizado, a assemblagem serializador será carregada, utilizando o método LoadFrom . Se o argumento AssemblyName for utilizado, a assemblagem serializador será carregada, utilizando o método LoadWithPartialName . Para mais informações sobre a assemblagem a carregar, visite o seguinte Web site da Microsoft:
http://blogs.msdn.com/suzcook/ (http://blogs.msdn.com/suzcook/)
Se pretender instalar as assemblagens serializador para o Global assemblagem (GAC), cache deve utilizar o argumento AssemblyName , e fornecer o nome de assemblagem totalmente qualificado.

As aplicações que são implementadas por utilizando métodos de cliente inteligente

Se a assemblagem que contém o proxy está carregado e é executada a partir do computador local, é preferível a utilizar a sintaxe codebase para o atributo XmlSerializerAssemblyAttribute . Neste caso, a assemblagem serializador deve ser implementada para a mesma pasta que a assemblagem que contém o proxy. Por exemplo, se a assemblagem é carregada, utilizando o método LoadFrom através de HTTP num cenário de Implementação cliente inteligente, a assemblagem da seriação será não correctamente carregada pelo atributo XmlSerializerAssemblyAttribute . Este problema ocorre porque a assemblagem proxy existe no contexto LoadFrom comuns idioma o carregador de tempo de execução é em vez de no contexto de carga em , e a pesquisa não ocorre. Para resolver este problema, utilize a sintaxe AssemblyName outra que é suportada pelo atributo com um nome de assemblagem fictício.
[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName="LoadMySerializerAssemblyNow")]
A aplicação seguida, pode implementar uma rotina de tratamento para o AppDomain é o evento AssemblyResolve para interceptar o pedido para carregar a assemblagem serializador e carregá-lo a partir da localização correcta.
private void Form1_Load(object sender, System.EventArgs e)
{
			AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
}
static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
 {
			Assembly a = null;
			string serializationAssemblyPartialName = "LoadMySerializerAssemblyNow";
if (args.Name == serializationAssemblyPartialName)
	{string sSerializersDLL = "<Name Of The Serializer DLL>";
string smartDeploymentHostLocation = "<Full path location to the Serializer DLL>";
a = Assembly.LoadFrom(smartDeploymentHostLocation + sSerializersDLL);
}
			return a;
		}

Exemplo pregenerator alternativo

Segue-se uma versão mais sofisticada da aplicação de exemplo pregenerator serializador. Esta versão permite criar assemblagens serializador assinado. Utilizar o código que se segue.
namespace PreGenNS 
{
	using System;
	using System.Collections;
	using System.IO;
	using System.Reflection;
	using System.Xml.Serialization;
	using System.Text;
	using System.Globalization;
	using System.Web.Services.Protocols;
	using System.Threading;
	using System.CodeDom.Compiler;
	using System.Diagnostics;
	using System.Text.RegularExpressions;

	public class Pregen 
	{
		private static bool _verbose = true;

		
		// We use this as the standard suffix on all the serializer DLLs.
		// It must match the short name of the proxy assembly class with 
		const string SerializerSuffix = ".Serializer.dll";

		
		/// Key in the app config file with path of AssemblyInfo file.
		private const string AssemblyInfoAppKey = "AssemblyInfoFile";

		//private const string CSCCmd = "csc.exe";
		// Obtain the full path for the compiler, just in case the path is not set correctly

		private readonly string CSCCmd = System.Runtime.InteropServices.RuntimeEnvironment.RuntimeDirectory() + "csc.exe";

		public static int Main(string[] args) {		
			// Are we in a recursive call?
			//TODO: could really use a single value -- use filesToDelete...
			if (AppDomain.CurrentDomain.GetData(CallingAppDomainKey) == null) {
				return RunSlave(args);
			}

			string dllName = "";
			bool invalidUsage = false;

			if(args.Length == 1)
			{
				dllName = args[0];
			}
			else if(args.Length == 2)
			{
				if(!(args[0] == "/Q" || args[0] == "/q"))
				{
					invalidUsage = true;
				}
				else
				{
					dllName = args[1];
					_verbose = false;
				}
			}
			else 
			{
				invalidUsage = true;
			}

			if (invalidUsage)
			{
				Console.WriteLine("usage: ");
				Console.WriteLine(" pregen [/Q] assembly");
				return 1;
			}
			

			// Update Private path setting in current application domain
			if (updatePrivatePath() != 0)
			{
				return 1;
			}
			
			Pregen pregen = new Pregen();
			int rc = pregen.Run(dllName);
			//Console.Read();
			return rc;
		}


		// Reads private path settings from config file and updates appdomain.  This permits configurable probing that is needed for preserialization.
		static int updatePrivatePath()
		{
			string defaultPrivatePath = System.Configuration.ConfigurationSettings.AppSettings["PregenDefaultPrivatePath"];
			string dynamicPrivatePath = System.Configuration.ConfigurationSettings.AppSettings["PregenDynamicPrivatePath"];
			string env_PREGEN_VALUES = Environment.GetEnvironmentVariable("PREGEN_VALUES");
			string [] replacementBlocks, temp;

			if (_verbose)
				Console.WriteLine("Read PREGEN_VALUES Env Variable, Value = " + env_PREGEN_VALUES);

			//process the dynamic path if the environment variable PREGEN_VALUES is present 
			if (env_PREGEN_VALUES == null || env_PREGEN_VALUES == "")
			{
				if (defaultPrivatePath != null && defaultPrivatePath != "")
				{
					AppDomain.CurrentDomain.AppendPrivatePath(defaultPrivatePath);

					if (_verbose)
						Console.WriteLine("Appended private path with: " + defaultPrivatePath);
				}
			}
			else
			{
				if (dynamicPrivatePath != null && dynamicPrivatePath != "")
				{
					//do substitutions in dynamic path
					replacementBlocks = env_PREGEN_VALUES.ToUpper().Split(";".ToCharArray());
					dynamicPrivatePath = dynamicPrivatePath.ToUpper();

					for(int i = 0; i < replacementBlocks.Length; i++)
					{
						temp = replacementBlocks[i].Split("=".ToCharArray());
						if(temp.Length != 2)
						{
							Console.Error.WriteLine("Invalid Environment Variable format - PREGEN_VALUES");
							return 1;
						}

						dynamicPrivatePath = dynamicPrivatePath.Replace(temp[0],temp[1]);
					}
					
					AppDomain.CurrentDomain.AppendPrivatePath(dynamicPrivatePath);

					if (_verbose )
						Console.WriteLine("Appended private path with: " + dynamicPrivatePath);
				}
			}
			return 0;
		}
		
		int Run(string assemblyName) 
		{

			try 
			{
				GenerateAssembly(assemblyName);
			}
			catch (Exception e) 
			{
				if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) 
				{
					throw;
				}
				Error(e, "Error processing " + assemblyName + ": ");
				return 1;
			}
			return 0;
		}



		// Generates the serializer assembly for the proxy assembly specified
		void GenerateAssembly(string assemblyName) 
		{
			Assembly assembly = LoadAssembly(assemblyName, true);
			Type[] types = assembly.GetTypes();
			ArrayList mappings = new ArrayList();
			ArrayList importedTypes = new ArrayList();
			XmlReflectionImporter importer = new XmlReflectionImporter();

			
			//Obtain the imported serializable types
			for (int i = 0; i < types.Length; i++) 
			{
				Type type = types[i];
				if (HttpWebClientProtocol.GenerateXmlMappings(type, mappings)) 
				{
					importedTypes.Add(type);
				}
			}
			if (importedTypes.Count <= 0) {
				Console.Out.WriteLine("Assembly '{0}' does not contain any serializable types.", assembly.Location);
				return;
			}
 
			{
				Type[] serializableTypes = (Type[])importedTypes.ToArray(typeof(Type));
				XmlMapping[] allMappings = (XmlMapping[])mappings.ToArray(typeof(XmlMapping));

				bool wasError = false;
				bool gac = assembly.GlobalAssemblyCache;
				string codePath = gac ? Environment.CurrentDirectory : Path.GetDirectoryName(assembly.Location);

				//adjust compiler params
				CompilerParameters parameters = new CompilerParameters();
				parameters.GenerateInMemory = false;
				parameters.IncludeDebugInformation = false;
				parameters.TempFiles = new TempFileCollection(codePath, true);
				
				//generate the serializer
				Assembly serializer = XmlSerializer.GenerateSerializer(serializableTypes, allMappings, parameters);
				if (serializer == null) {
					Console.Out.WriteLine("Failed pregenerate serializer for '{0}'", assembly.Location);
					wasError = true;
				}
				else 
				{
					serializer = null;
				}

				// Determine whether there is an assemblyInfoFile in the config file.
				string assemblyInfoFile = System.Configuration.ConfigurationSettings.AppSettings[AssemblyInfoAppKey];
				if (assemblyInfoFile != null) { 
					if (! File.Exists(assemblyInfoFile)) {
						Console.WriteLine("ERROR: AssemblyInfo file: {0} does not exist.", assemblyInfoFile);
						wasError = true;
					}
				}

				if (!wasError) {
					// Recompile the Serializer, same options, except to include the assemblyInfo file and
					// adjust the output name.

					// We have to find 
					//		1. a .cs file (the serializer source)
					//		2. a .cmdline file (the compiler options used)
					// among the temp files from the first compile.
					
					string csFile		= null;
					string cmdlineFile	= null;

					foreach (string curFile in parameters.TempFiles ) {
						string fileNameLC = curFile.ToLower();
						if (fileNameLC.EndsWith(".cs") ) {
							csFile = curFile;
						}
						else if (fileNameLC.EndsWith(".cmdline")) {
							cmdlineFile = curFile;
						}
						//Do not care about the other files...
					}
					if (csFile == null || cmdlineFile == null) {
						Console.WriteLine("Error: needed to rebuild, but cannot find either .cs or .cmdline file\n");
						DeleteTempFiles(parameters);
						return;
					}

					// So now we have found the file and the cmdline args.  We only need run the compiled application after 
					// adjusting the parameters to include the AssemblyInfo file and to change the output.
					
					// Typical calling options to csc for this sequence are:
					//		csc /noconfig @xxx.cmdline
					// we'll change this to expand the contents of the cmdline file

					// build the right name for the target serializer.
					//TODO: we should be able to read the attribute from the proxy DLL and match our output
					// to that name.
					string serializerName = Path.GetDirectoryName(assembly.Location) + @"\" 
											+ assembly.GetName().Name + SerializerSuffix;

					string cmdLine = AdjustCmdLine(cmdlineFile, assemblyInfoFile, serializerName);

					ProcessStartInfo ps = new ProcessStartInfo(CSCCmd, cmdLine);
					ps.WindowStyle = ProcessWindowStyle.Hidden;
					Process p = Process.Start(ps);
					p.WaitForExit();
					int rc = p.ExitCode;
					if (rc > 0) {
						//TODO: put useful handling here...
						Console.WriteLine("ERROR: Compiler problem, rc = {0}", rc);
						wasError = true;
					}

					//TODO: Cannot ditch temp assembly because the assembly is now loaded.
					DeleteTempFiles(parameters);

					if (!wasError) {
						Console.Out.WriteLine("Generated Serialization Assembly Name: {0}", serializerName);
					}
					Console.Out.WriteLine("Done");
				}
			}
		}


		// Delete temporary files from a CompilerParameters list.
		private void DeleteTempFiles(CompilerParameters cp) {
			ArrayList unDeletedFiles = new ArrayList(10);
			foreach(string fileName in cp.TempFiles) {
				try {
					File.Delete(fileName);
				}
				catch(Exception) {
					unDeletedFiles.Add(fileName);
					//Console.WriteLine("Warning: Unable to delete temp file: {0}, exception={1}(\"{2}\")",
					//	Path.GetFileName(fileName), e.GetType().FullName, e.Message);
				}
			}
			if (unDeletedFiles.Count > 0) {
				// put the list into the calling appDomain's environment for later deletion
				string[] files = new string[unDeletedFiles.Count];
				unDeletedFiles.CopyTo(files);

				//TODO: should really be concatenating to any existing value -- maybe leave as an ArrayList?
				AppDomain.CurrentDomain.SetData(FilesToDeleteKey, files);
			}
		}


		/// Rebuild a commandline for csc, adding assemblyInfoFile to the end of the line and adjusting the 
		/// output file name as specified.
		private string AdjustCmdLine(string cmdlineFile, string assemblyInfoFile, string outputFile) {	
			// Obtain the text from the @ response file that is used by the Framework Serialization builder
			StreamReader file = File.OpenText(cmdlineFile);
			string cmdLine = file.ReadToEnd();
			file.Close();

			// add the assemblyInfo file at the end of the command if it was specified
			if (assemblyInfoFile != null)
				cmdLine = String.Format(@"/noconfig {0} ""{1}""", cmdLine, assemblyInfoFile);

			// replace the /OUT option with our value.
			Regex re = new Regex(@"/OUT:""[^""]+.", RegexOptions.IgnoreCase);
			cmdLine = re.Replace(cmdLine, @"/OUT:""" + outputFile + @"""");

			return cmdLine;
		}

		static Assembly LoadAssembly(string assemblyName, bool throwOnFail) 
		{
			Assembly assembly = null;
			string path = Path.GetFullPath(assemblyName).ToLower(CultureInfo.InvariantCulture);
			if (File.Exists(path)) 
			{
				assembly = Assembly.LoadFrom(path);
			}
			else 
			{
				try 
				{
					assembly = Assembly.Load(assemblyName);
				}
				catch (Exception e) 
				{
					if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) 
					{
						throw;
					}
					Error(e, "Error: ");
				}
				if (assembly == null) 
				{
					string justName = Path.GetFileNameWithoutExtension(assemblyName);
					try 
					{
						assembly = Assembly.Load(justName);
					}
					catch (Exception e) 
					{
						if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) 
						{
							throw;
						}
						Error(e, "Error: ");
					}
				}
			}
			if (assembly == null) 
			{
				if (throwOnFail)
					throw new InvalidOperationException("Cannot load assembly " + assemblyName);
				return null;
			}
			return assembly;
		}

		static void Error(Exception e, string prefix) 
		{
			Console.Error.WriteLine(prefix + e.Message);
			if (e.InnerException != null) 
			{
				Error(e.InnerException, " - ");
			}
		}

		static void Warning(Exception e) 
		{
			Console.Out.WriteLine(" - " + e.Message);
			if (e.InnerException != null) 
			{
				Warning(e.InnerException);
			}
		}

		private static AppDomain DuplicateAppDomain(AppDomain template, string newName) {
			AppDomain res = AppDomain.CreateDomain(newName, template.Evidence, template.SetupInformation);
			return res;
		}

		// keys in AppDomain properties
		private const string CallingAppDomainKey	= "__Calling_AppDomain__";
		private const string FilesToDeleteKey		= "__Files_To_Delete__";

		// Called from Main to set up and run the second copy of the program.
		// args: command-line arguments for second execution
		private static int RunSlave(string[] args) {

			// Start a copy of this program in another application domain
			AppDomain ad = DuplicateAppDomain(AppDomain.CurrentDomain, "serializerAD");
			Assembly ca = Assembly.GetExecutingAssembly();

			// set a marker so target domain knows that it is the subordinate.
			ad.SetData(CallingAppDomainKey, AppDomain.CurrentDomain.FriendlyName);
			ad.SetData(FilesToDeleteKey, new string[0]);

			int rc = ad.ExecuteAssembly(ca.Location, ca.Evidence, args);

			// Now delete any files
			string[] fileList = (string[])ad.GetData(FilesToDeleteKey);

			AppDomain.Unload(ad);

			if (fileList != null) {
				foreach(string fileName in fileList) {
					try {
						File.Delete(fileName);
					}
					catch(Exception e) {
						Console.WriteLine("Warning: Unable to delete temp file: {0}, exception={1}(\"{2}\")",
							Path.GetFileName(fileName), e.GetType().FullName, e.Message);
					}
				}
			}
			return rc;  
		}

	}
}

Referências

Para mais informações, visite os seguintes sites da Web MSDN:
http://msdn2.microsoft.com/en-us/library/y92e0td0(vs.71).aspx (http://msdn2.microsoft.com/en-us/library/y92e0td0(vs.71).aspx)
http://msdn2.microsoft.com/en-us/library/hk7y1596(vs.71).aspx (http://msdn2.microsoft.com/en-us/library/hk7y1596(vs.71).aspx)

A informação contida neste artigo aplica-se a:
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.1 Service Pack 1
  • Microsoft Visual Studio .NET 2003 Enterprise Architect
  • Microsoft Visual Studio .NET 2003 Enterprise Developer
  • Microsoft Visual Studio .NET 2003 Professional Edition
  • Microsoft Visual Studio .NET 2003 Academic Edition
Palavras-chave: 
kbqfe kbhotfixserver kbtshoot kbdll kbwebservices kbuser kbarchitecture kbfix KB872800 KbMtpt kbmt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Pedíamos-lhe o favor de preencher o formulário existente no fundo desta página caso venha a encontrar erros neste artigo e tenha possibilidade de colaborar no processo de aperfeiçoamento desta ferramenta. Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 872800  (http://support.microsoft.com/kb/872800/en-us/ )