<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Microsoft XML Team's WebLog : threading</title><link>http://blogs.msdn.com/xmlteam/archive/tags/threading/default.aspx</link><description>Tags: threading</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>XmlSchemaSet Thread Safety</title><link>http://blogs.msdn.com/xmlteam/archive/2009/04/27/xmlschemaset-thread-safety.aspx</link><pubDate>Tue, 28 Apr 2009 00:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9572118</guid><dc:creator>XmlTeam</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/xmlteam/comments/9572118.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xmlteam/commentrss.aspx?PostID=9572118</wfw:commentRss><description>&lt;P&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN"&gt;Here's a good word of warning: even if an object "feels" read-only because you're not calling code to modify it, if it's not documented as safe for use from multiple threads, then you shouldn't risk it.&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN"&gt;As an example, let’s look at &lt;A href="http://msdn.microsoft.com/en-us/library/system.xml.schema.xmlschema.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.xml.schema.xmlschema.aspx"&gt;&lt;FONT color=#0000ff&gt;XmlSchema&lt;/FONT&gt;&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/en-us/library/system.xml.schema.xmlschemaset.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.xml.schema.xmlschemaset.aspx"&gt;&lt;FONT color=#0000ff&gt;XmlSchemaSet&lt;/FONT&gt;&lt;/A&gt;. Initializing these has a cost associated with it, and so it's nice to be able to build them once and then reuse them. But you have to be very careful in doing this. The docs say that all instance methods are not safe for multiple thread usage, but you don't really use them directly during validation, so it's hard to tell from the outside what's safe and what's not.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN"&gt;In a nutshell, the only thing you can do that is safe for concurrent usage is to use a validating reader. Here's the sample code to try this out (for some reason, this "breaks" more on 64-bit machines, but it's unsafe on all architectures).&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN"&gt;First, a little helper to create an XmlSchema.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas; mso-ansi-language: EN"&gt;private&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-ansi-language: EN"&gt; &lt;SPAN style="COLOR: #2b91af"&gt;XmlSchema&lt;/SPAN&gt; CreateSchema()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; schemaText = &lt;SPAN style="COLOR: #a31515"&gt;@"&amp;lt;?xml version='1.0'?&amp;gt;&lt;BR&gt;&amp;lt;xs:schema id='play' targetNamespace='http://tempuri.org/play.xsd'&lt;BR&gt;&amp;nbsp;elementFormDefault='qualified' xmlns='http://tempuri.org/play.xsd'&lt;BR&gt;&amp;nbsp;xmlns:xs='http://www.w3.org/2001/XMLSchema'&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;xs:element name='myShoeSize'&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;xs:complexType&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;xs:simpleContent&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xs:extension base='xs:decimal'&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xs:attribute name='sizing' type='xs:string' /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/xs:extension&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/xs:simpleContent&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/xs:complexType&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;/xs:element&amp;gt;&lt;BR&gt;&amp;lt;/xs:schema&amp;gt;"&lt;/SPAN&gt;;&lt;BR&gt;&lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;StringReader&lt;/SPAN&gt; reader = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;StringReader&lt;/SPAN&gt;(schemaText))&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;XmlSchema&lt;/SPAN&gt;.Read(reader, &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN"&gt;Next, a simple XmlSchemaSet.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas; mso-ansi-language: EN"&gt;private&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-ansi-language: EN"&gt; &lt;SPAN style="COLOR: #2b91af"&gt;XmlSchemaSet&lt;/SPAN&gt; CreateSchemaSet(&lt;SPAN style="COLOR: #2b91af"&gt;XmlSchema&lt;/SPAN&gt; schema)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;XmlSchemaSet&lt;/SPAN&gt; set = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;XmlSchemaSet&lt;/SPAN&gt;();&lt;BR&gt;&amp;nbsp; set.Add(schema);&lt;BR&gt;&amp;nbsp; set.Compile();&lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; set;&lt;BR&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN"&gt;Finally, some validation:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas; mso-ansi-language: EN"&gt;private&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-ansi-language: EN"&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; ValidateDocument(&lt;SPAN style="COLOR: #2b91af"&gt;XmlSchemaSet&lt;/SPAN&gt; set)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; doc = &lt;SPAN style="COLOR: #a31515"&gt;@"&amp;lt;myShoeSize xmlns='http://tempuri.org/play.xsd' sizing='123' /&amp;gt;"&lt;/SPAN&gt;;&lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;XmlReaderSettings&lt;/SPAN&gt; settings = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;XmlReaderSettings&lt;/SPAN&gt;();&lt;BR&gt;&amp;nbsp; settings.Schemas = set;&lt;BR&gt;&amp;nbsp; settings.ValidationEventHandler += &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ValidationEventHandler&lt;/SPAN&gt;(settings_ValidationEventHandler);&lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;StringReader&lt;/SPAN&gt; reader = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;StringReader&lt;/SPAN&gt;(doc))&lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;XmlReader&lt;/SPAN&gt; x = &lt;SPAN style="COLOR: #2b91af"&gt;XmlReader&lt;/SPAN&gt;.Create(reader, settings))&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;while&lt;/SPAN&gt; (x.Read()) { }&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;private&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; failCount;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;BR&gt;void&lt;/SPAN&gt; settings_ValidationEventHandler(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR: #2b91af"&gt;ValidationEventArgs&lt;/SPAN&gt; e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; System.Threading.&lt;SPAN style="COLOR: #2b91af"&gt;Interlocked&lt;/SPAN&gt;.Increment(&lt;SPAN style="COLOR: blue"&gt;ref&lt;/SPAN&gt; failCount);&lt;BR&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN"&gt;Now, armed with these, I will show you some code that &lt;EM&gt;is&lt;/EM&gt; thread-safe, but that a single line reorder would cause to break.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: #2b91af; FONT-FAMILY: Consolas; mso-ansi-language: EN"&gt;XmlSchema&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-ansi-language: EN"&gt; schema = CreateSchema();&lt;BR&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Thread&lt;/SPAN&gt;[] threads = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Thread&lt;/SPAN&gt;[10];&lt;BR&gt;&lt;SPAN style="COLOR: #2b91af"&gt;XmlSchemaSet&lt;/SPAN&gt; set = CreateSchemaSet(schema);&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; i = 0; i &amp;lt; threads.Length; i++)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; threads[i] = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Thread&lt;/SPAN&gt;((x) =&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; j = 0; j &amp;lt; 1000; j++)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// If the CreateSchemaSet were here&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // instead of outside this would break!&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Don't add the schema to the &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // XmlSchemaSet from multiple threads!&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // XmlSchemaSet set = CreateSchemaSet(schema);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ValidateDocument(set);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Array&lt;/SPAN&gt;.ForEach(threads, (t) =&amp;gt; t.Start());&lt;BR&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Array&lt;/SPAN&gt;.ForEach(threads, (t) =&amp;gt; t.Join());&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.Text = &lt;SPAN style="COLOR: #a31515"&gt;"Failure count: "&lt;/SPAN&gt; + failCount;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-FAMILY: Consolas; mso-ansi-language: EN"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN"&gt;The part before the thread creation runs on a single thread, and so there are no multi-thread concerns; the stuff inside the callback&amp;nbsp;is happening on multiple threads at the same time. You can only use the set for validation here!&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Enjoy!&lt;/P&gt;
&lt;P&gt;Marcelo Lopez Ruiz&lt;/P&gt;
&lt;P&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN"&gt;&lt;o:p&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN"&gt;&lt;FONT size=3&gt;&lt;FONT face="Times New Roman"&gt;&lt;A href="http://blogs.msdn.com/marcelolr/"&gt;http://blogs.msdn.com/marcelolr/&lt;/A&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/o:p&gt;&lt;/SPAN&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9572118" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/xmlteam/archive/tags/XSD/default.aspx">XSD</category><category domain="http://blogs.msdn.com/xmlteam/archive/tags/Schema+Validation/default.aspx">Schema Validation</category><category domain="http://blogs.msdn.com/xmlteam/archive/tags/xml/default.aspx">xml</category><category domain="http://blogs.msdn.com/xmlteam/archive/tags/threading/default.aspx">threading</category></item></channel></rss>