C# net中基于模式的多线程xml验证

C# net中基于模式的多线程xml验证,c#,xml,multithreading,validation,xml-parsing,C#,Xml,Multithreading,Validation,Xml Parsing,我正在尝试验证多线程应用程序中的xml文件,但遇到了一些问题(验证错误:未声明“”元素)。如果我使用单个线程运行代码,或者一次只使用一个xml文件,则一切正常 我相信这和这个问题是同一个问题,但是我不知道如何让它起作用 我最初使用的是内联模式,这很好,但是太慢了,无法解析外部文件。我决定将模式缓存在ConcurrentDictionary中以加快速度 代码如下: 此方法属于每个线程的本地对象 public void validate() { XmlReaderSettings sett

我正在尝试验证多线程应用程序中的xml文件,但遇到了一些问题(验证错误:未声明“”元素)。如果我使用单个线程运行代码,或者一次只使用一个xml文件,则一切正常

我相信这和这个问题是同一个问题,但是我不知道如何让它起作用

我最初使用的是内联模式,这很好,但是太慢了,无法解析外部文件。我决定将模式缓存在ConcurrentDictionary中以加快速度

代码如下:

此方法属于每个线程的本地对象

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多线程的具体教程。