文章編號: 872800 - 上次校閱: 2007年5月18日 - 版次: 3.4

FIX: Web 服務用戶端產生序列化組件在每次應用程式執行時,

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

徵狀

比預期要進行第一次呼叫在與後續呼叫會進行比較時, 呼叫 Web 服務的應用程式可能會花上更久的時間。 您執行應用程式會在每次發生這個延遲。

請注意 這個 Hotfix 無法套用在執行 Microsoft . NET Framework 1.1 Service Pack 1 系統上。 如果您安裝了 . NET Framework 1.1 版 Service Pack 1, 會遇到徵狀, 本篇文章中所描述要求 Hotfix Rollup Package 890673, 以取得解決方案 Microsoft 知識庫 」 文件中所述。 如需詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件::
890673? (http://support.microsoft.com/kb/890673/ ) .NET Framework 1.1 Post-Service Pack 1 XML Web 服務與 XML Messaging Hotfix Rollup Package 8 的可用性

發生的原因

當您執行在第一次用戶端應用程式因為序列化 (Serialization) 組件, 使用 Web 服務 Proxy, 序列化 (Serialization) 組件在執行階段動態地編譯延遲。 序列化 (Serialization) 組件則序列化和還原序列化資訊, 以根據用戶端要求和伺服器要用於要求所傳回的結果。 因為發生序列化 (Serialization) 組件的編譯就會發生在第一次呼叫額外的時間。

解決方案

這個 Hotfix 也必須安裝在執行 pregenerated 組件使用您的應用程式的電腦上。 如果要解決這個問題, 請依照下列步驟執行:
  1. 取得並安裝此 Hotfix。 如果要執行這項操作,請依照下列步驟執行。:
    1. 從下列 Hotfix 套件取得此 Hotfix:
      890673? (http://support.microsoft.com/kb/890673/ ) .NET Framework 1.1 Post-Service Pack 1 XML Web 服務與 XML Messaging Hotfix Rollup Package 8 的可用性
    2. 解壓縮 Hotfix 以資料夾。
    3. 連按兩下 Hotfix 來在您的電腦上安裝 Hotfix。
  2. pregenerate 序列化程式組件。 下列是主控台最少, 範例應用程式會產生序列化程式組件為 Proxy 組件。 為更複雜的版本從這個應用程式, 請參閱 「 其他資訊 > 一節。 如果要建立簡單的序列化程式 pregenerator, 請依照下列步驟執行:
    1. 建立名為 PreGen 新 Microsoft Visual C# . NET 主控台應用程式。
    2. 將 Class 1. cs 檔案重新命名為 Pregen.cs。
    3. 以下列程式碼取代所有現有程式碼在 PreGen.cs 檔案。
      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. 將參考加入 System . Web . Services . dll 檔案。
    5. 建置專案。
    6. PreGen.exe 檔案複製到資料夾, 它應包含具有 Proxy 程式碼組件。 舉例來說, PreGen.exe 檔案複製到組件, 其中含有 Web 服務用戶端程式碼。
    7. 藉由使用備製 PreGen.exe 檔案 pregenerate 序列化工具針對 Web 服務。 在命令提示字元例如, 如果您的 Proxy 程式碼是在 WindowsApplication1.exe 檔案, 執行下列命令:

      PreGen.exe WindowsApplication1.exe

      注意 A . dll 檔案是在同一個資料夾儲存用戶端組件, 只要您在步驟 g 執行命令所產生。
    8. 在 Microsoft Visual Studio . NET IDE 開啟您的用戶端程式碼。
    9. 在 [ 方案總管 ], 展開 [ Web 參考 ] 節點。 舉例來說, 如果您藉由使用 localhost, 新增參考加入至 service1 展開 LocalHost 。
    10. 展開 Reference.map , 並再連按兩下 Reference.cs 檔案。
    11. 找出下列程式碼。
          [System.Diagnostics.DebuggerStepThroughAttribute()]
          [System.ComponentModel.DesignerCategoryAttribute("code")]
          [System.Web.Services.WebServiceBindingAttribute(Name="Service1Soap", Namespace="http://tempuri.org/")]
    12. 以下列程式碼取代程式碼在步驟 k。
      [System.Diagnostics.DebuggerStepThroughAttribute()]
      [System.ComponentModel.DesignerCategoryAttribute("code")]
      [System.Web.Services.WebServiceBindingAttribute(Name="Service1Soap", Namespace="http://tempuri.org/")]
      [System.Xml.Serialization.XmlSerializerAssemblyAttribute(CodeBase="DLL Name>")]
      
    13. 請重建您的 Web 服務用戶端。

      請注意 您必須重建的屬性, 因為您的用戶端。 組件, 該組件包含 MySerializers.dll 序列化程式上您的用戶端現在具有 Run - Time 依存性。 因此, 您必須與您的應用程式部署此組件並讓該組件可在其中載入您的用戶端位置。

其他相關資訊

組件繫結

引數, 您提供給 XmlSerializerAssemblyAttribute 屬性 (Attribute) 型別決定, 序列化程式組件所載入的方式。 如果是使用 [ CodeBase 引數, 序列化程式組件會載入藉由使用 LoadFrom 方法。 如果是使用 AssemblyName 引數, 序列化程式組件會載入藉由使用 LoadWithPartialName 方法。 如需組件載入, 請造訪下列 Microsoft 網站:
http://blogs.msdn.com/suzcook/ (http://blogs.msdn.com/suzcook/)
如果您想要您的序列化工具組件安裝到全域組件快取 (GAC), 您必須使用 AssemblyName 引數, 並提供完整組件名稱。

藉由使用智慧型用戶端方法部署的應用程式

如果包含 Proxy 組件載入及執行從本機電腦, 最好以使用 CodeBase 語法為 XmlSerializerAssemblyAttribute 屬性。 在這種情況下, 序列化程式組件應該部署到與 Proxy, 其中包含該組件相同的資料夾。 如果藉由在智慧型用戶端部署案例中, 使用 LoadFrom 方法透過 HTTP 將組件載入舉例來說, 序列化 (Serialization) 組件將不會被正確載入由 XmlSerializerAssemblyAttribute 屬性 (Attribute)。 就會發生, 因為 Proxy 組件存在於的 Common Language Runtime 載入器的 負載 內容, 而 LoadFrom 內容, 且探查不會發生這個問題。 如果要解決這個問題, 請使用其他 AssemblyName 語法由具有空的組件名稱屬性 (Attribute) 所支援。
[System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName="LoadMySerializerAssemblyNow")]
然後您的應用程式可以實作 AppDomain 的 AssemblyResolve 事件, 以攔截要求, 並將其從正確的位置載入序列化程式組件處理常式。
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;
		}

替代 pregenerator 範例

下列是更複雜的序列化程式 pregenerator 範例應用程式的版本。 這個版本允許建立序列化程式已簽署組件。 請使用下列程式碼。
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;  
		}

	}
}

?考

如需詳細資訊,請造訪下列 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)

這篇文章中的資訊適用於:
  • 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
關鍵字:?
kbqfe kbhotfixserver kbtshoot kbdll kbwebservices kbuser kbarchitecture kbfix KB872800 KbMtzh kbmt
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。如果您發現錯誤,並想要協助我們進行改善,請填寫本篇文章下方的問卷。
按一下這裡查看此文章的英文版本:872800? (http://support.microsoft.com/kb/872800/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。