用Task多线程操作C#T4生成代码,抛出System.ObjectDisposedException: 已关闭 Safe handle

Posted 棉晗榜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用Task多线程操作C#T4生成代码,抛出System.ObjectDisposedException: 已关闭 Safe handle相关的知识,希望对你有一定的参考价值。

抛出的异常:
ErrorGeneratingOutput
D:\\Work\\wanghaoli.Kalman.Studio\\Kalman.Studio\\src\\Kalman.Studio\\bin\\Debug\\T4Template\\whl实体2.tt(-1,-1) : error : An Exception was thrown while processing the template.
The following Exception was thrown:
System.ObjectDisposedException: 已关闭 Safe handle

如果是一般用单线程代码,不会导致异常,
抛出异常的代码:

//namespace Microsoft.VisualStudio.TextTemplating
//
//
// 摘要:
//     Text templating engine
//public class Engine : ITextTemplatingEngine, IDebugTextTemplatingEngine
Engine engine = new Engine();
var outputContent = engine.ProcessTemplate(templateContent, host);

解决办法:
将Task改为Task task = new Task(action,object)处理

示例代码:

private void DoBuild()

	//完成计数
	System.Collections.Concurrent.ConcurrentBag<int> finished = new System.Collections.Concurrent.ConcurrentBag<int>();

	int total = listBox2.Items.Count;
	System.Collections.Concurrent.ConcurrentBag<Task> taskList = new System.Collections.Concurrent.ConcurrentBag<Task>();

	//模板文件内容
	string templateFile = gbTemplateFile.Text;
	string templateContent = File.ReadAllText(templateFile);

	//遍历选中的表,一张表对应生成一个代码文件
	foreach (object item in listBox2.Items)
	
		/*
		 * 
		改成Task task = new Task(action,obj)处理解决下面的异常                
		 ErrorGeneratingOutput
D:\\Work\\wanghaoli.Kalman.Studio\\Kalman.Studio\\src\\Kalman.Studio\\bin\\Debug\\T4Template\\whl实体2.tt(-1,-1) : error : An Exception was thrown while processing the template.  
The following Exception was thrown:
System.ObjectDisposedException: 已关闭 Safe handle

		#如果使用此代码:public static Task Run(Action action)将导致如上的异常
		 * 
		 */

		//多线程处理提高速度;        
		Task task = new Task(
			(g) =>
		
			SOTable table = g as SOTable;
			string className = table.Name;
			if (cbDeleteTablePrifix.Checked) className = table.Name.RemovePrefix(tablePrefix, prefixLevel).Replace(" ", "");

			//类文件名帕斯卡命名
			if (cbClassNamePascal.Checked) className = className.InitialToUpperMulti();

			if (cbClassNameRemovePlural.Checked) className = className.EndsWith("s") ? className.TrimEnd('s') : className.Trim();
			if (cbAddSuffix.Checked) className = txtClassPrefix.Text.Trim() + className + txtClassSuffix.Text.Trim();

			List<SOColumn> columnList = table.ColumnList;//可能传入的是从PDObject对象转换过来的SODatabase对象
			if (columnList == null || columnList.Count == 0) columnList = DbSchemaHelper.Instance.CurrentSchema.GetTableColumnList(table);

			//生成代码文件
			TableHost host = new TableHost();
			host.Table = table;
			host.ColumnList = columnList;
			host.TemplateFile = templateFile;
			host.SetValue("NameSpace", nameSpace);
			host.SetValue("ClassName", className);
			host.SetValue("TablePrefix", tablePrefix);
			//host.SetValue("ColumnPrefix", columnPrefix);
			host.SetValue("PrefixLevel", prefixLevel);

			//模板引擎生成代码
			Engine engine = new Engine();
			var outputContent = engine.ProcessTemplate(templateContent, host);

			string outputFile = Path.Combine(outputPath, string.Format("01", table.Name, host.FileExtention));
			if (cbClassNameIsFileName.Checked) outputFile = Path.Combine(outputPath, string.Format("01", className, host.FileExtention));

			StringBuilder sb = new StringBuilder();
			if (host.ErrorCollection != null && host.ErrorCollection.HasErrors)
			
				foreach (CompilerError err in host.ErrorCollection)
				
					sb.AppendLine(err.ToString());
				
				outputContent = outputContent + Environment.NewLine + sb.ToString();
				outputFile = outputFile + ".error";
			

			if (Directory.Exists(outputPath) == false) Directory.CreateDirectory(outputPath);
			File.WriteAllText(outputFile, outputContent, Encoding.UTF8);

			//进度计算
			finished.Add(1);
			int percent = ConvertUtil.ToInt32(finished.Count * 100 / total, 0);
			backgroundWorker1.ReportProgress(percent, table);
		,
			item);
		task.Start();
		taskList.Add(task);

	//end build code foreach

	Task.WaitAll(taskList.ToArray());

以上是关于用Task多线程操作C#T4生成代码,抛出System.ObjectDisposedException: 已关闭 Safe handle的主要内容,如果未能解决你的问题,请参考以下文章

C#中如果用await关键字来await一个为null的Task对象会抛出异常

C#/.NET 多线程任务Task的详解——应用实例

多线程Task

C# Task总结(异步操作+并行)

java线程操作

多线程-Taskawait/async