C# net中基于模式的多线程xml验证
我正在尝试验证多线程应用程序中的xml文件,但遇到了一些问题(验证错误:未声明“”元素)。如果我使用单个线程运行代码,或者一次只使用一个xml文件,则一切正常 我相信这和这个问题是同一个问题,但是我不知道如何让它起作用 我最初使用的是内联模式,这很好,但是太慢了,无法解析外部文件。我决定将模式缓存在ConcurrentDictionary中以加快速度 代码如下: 此方法属于每个线程的本地对象C# net中基于模式的多线程xml验证,c#,xml,multithreading,validation,xml-parsing,C#,Xml,Multithreading,Validation,Xml Parsing,我正在尝试验证多线程应用程序中的xml文件,但遇到了一些问题(验证错误:未声明“”元素)。如果我使用单个线程运行代码,或者一次只使用一个xml文件,则一切正常 我相信这和这个问题是同一个问题,但是我不知道如何让它起作用 我最初使用的是内联模式,这很好,但是太慢了,无法解析外部文件。我决定将模式缓存在ConcurrentDictionary中以加快速度 代码如下: 此方法属于每个线程的本地对象 public void validate() { XmlReaderSettings sett
public void validate()
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
//settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
//settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler +=
new ValidationEventHandler(ValidationCallBack);
using (var tr = new XmlTextReader(xmlFile))
{
tr.MoveToContent();
var url = tr.GetAttribute("xsi:noNamespaceSchemaLocation");
var schema = SchemaFactory.GetSchema(url);
settings.Schemas.Add(schema);
}
using (XmlReader reader = XmlReader.Create(xmlFile, settings))
{
while (reader.Read());
}
SchemaFactory定义:
public static class SchemaFactory
{
static ConcurrentDictionary<string, XmlSchema> schemaStore =
new ConcurrentDictionary<string, XmlSchema>();
public static XmlSchema GetSchema(string url)
{
XmlSchema schema = null;
if (!schemaStore.TryGetValue(url, out schema))
{
var schemadata = new System.Net.WebClient().DownloadString(url);
schema = XmlSchema.Read(new StringReader(schemadata), (sender, args) => { });
schemaStore.TryAdd(url, schema);
}
return schema;
}
}
公共静态类SchemaFactory
{
静态ConcurrentDictionary模式存储=
新的ConcurrentDictionary();
公共静态XmlSchema GetSchema(字符串url)
{
XmlSchema=null;
if(!schemaStore.TryGetValue(url,out schema))
{
var schemadata=new System.Net.WebClient().DownloadString(url);
schema=XmlSchema.Read(新的StringReader(schemadata),(发送方,args)=>{});
TryAdd(url,schema);
}
返回模式;
}
}
当在多线程中处理xml文件时,如何在第一次遇到模式时将其实时添加到缓存中?如果仍然是这样,即不能对同一个编译模式运行多个并行模式验证,那么解决方法可能是使用Saxon模式验证程序[无耻的插件]没有这个限制
XMLSchema不是线程安全的。将架构缓存为字符串,然后它工作:
class Program
{
private ConcurrentDictionary<string, string> schemaStore =
new ConcurrentDictionary<string, string>();
static void Main(string[] args)
{
Program p = new Program();
for (int i = 0; i < 40;i++ )
new Thread(new ThreadStart(p.validate)).Start();
Console.ReadKey();
}
public void validate()
{
string xmlFile = "XMLFile1.xml";
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
//settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
//settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler +=
new ValidationEventHandler(ValidationCallBack);
using (var tr = new XmlTextReader(xmlFile))
{
tr.MoveToContent();
var url = tr.GetAttribute("xsi:noNamespaceSchemaLocation");
string schemaXml =null;
if (!schemaStore.TryGetValue(url, out schemaXml))
{
//Console.WriteLine("Need download");
using (System.Net.WebClient wc = new System.Net.WebClient())
{
string schemadata = wc.DownloadString(url);
schemaStore.TryAdd(url, schemadata);
schemaXml = schemadata;
}
}else
{
//Console.WriteLine("Cache hit");
}
XmlSchema schema = XmlSchema.Read(new StringReader(schemaXml), (sender, args) => { });
settings.Schemas.Add(schema);
}
using (XmlReader reader = XmlReader.Create(xmlFile, settings))
{
while (reader.Read()) ;
}
Console.WriteLine("Thread "+Thread.CurrentThread.ManagedThreadId+" completes");
}
private void ValidationCallBack(object sender, ValidationEventArgs args)
{
if (args.Severity == XmlSeverityType.Error)
Console.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " -> Error: " + args.Message);
else
Console.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " -> Warning: " + args.Message);
}
}
类程序
{
私有并发字典模式=
新的ConcurrentDictionary();
静态void Main(字符串[]参数)
{
程序p=新程序();
对于(int i=0;i<40;i++)
新线程(newthreadstart(p.validate)).Start();
Console.ReadKey();
}
public void validate()
{
字符串xmlFile=“XMLFile1.xml”;
XmlReaderSettings设置=新建XmlReaderSettings();
settings.ValidationType=ValidationType.Schema;
//settings.ValidationFlags |=XmlSchemaValidationFlags.ProcessInlineSchema;
//settings.ValidationFlags |=XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |=XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler+=
新的ValidationEventHandler(ValidationCallBack);
使用(var tr=新的XmlTextReader(xmlFile))
{
tr.MoveToContent();
var url=tr.GetAttribute(“xsi:noNamespaceSchemaLocation”);
字符串schemaXml=null;
if(!schemaStore.TryGetValue(url,out schemaXml))
{
//Console.WriteLine(“需要下载”);
使用(System.Net.WebClient wc=new System.Net.WebClient())
{
string schemadata=wc.DownloadString(url);
TryAdd(url,schemadata);
schemaXml=schemadata;
}
}否则
{
//控制台写入线(“缓存命中”);
}
XmlSchema=XmlSchema.Read(新的StringReader(schemaXml),(发送方,args)=>{});
settings.Schemas.Add(schema);
}
使用(XmlReader=XmlReader.Create(xmlFile,设置))
{
while(reader.Read());
}
WriteLine(“线程”+线程.CurrentThread.ManagedThreadId+“完成”);
}
私有void ValidationCallBack(对象发送方,ValidationEventArgs参数)
{
if(args.Severity==XmlSeverityType.Error)
Console.WriteLine(“线程”+Thread.CurrentThread.ManagedThreadId+”->错误:+args.Message);
其他的
Console.WriteLine(“线程”+Thread.CurrentThread.ManagedThreadId+”->警告:“+args.Message”);
}
}
与编写的另一个线程一样,您可以尝试创建XmlSchema对象列表并包装对其的访问。因此,每个线程只使用一个线程,并在完成时释放它们。如果要插入某些内容,您是否至少可以在文档或示例中提供指向正确部分的链接?好的,这将取决于,例如,您是想使用Java还是.NET,如果是Java,你是否有足够的知识来阅读Javadocs并直接投入其中。例如,您找不到任何关于如何执行Java多线程的具体教程。