Любые общедоступные статические члены XmlDocument являются потокобезопасными. Любые члены экземпляра не гарантируют потокобезопасность: да, но

Я вижу в документации класса XmlDocument в MSDN, что

Любые общедоступные статические (Shared в Visual Basic) члены этого типа являются потокобезопасными. Любые члены экземпляра не гарантируют потокобезопасность.

То же самое для класса XmlNodeList.

Я использую эти классы в следующем контексте. Внутри Parallel.Foreach я делаю:

X MyX = new X();
string XMLstring = MyX.GetXML(ID, true);
XmlDocument doc = new XmlDocument();
doc.LoadXml(XMLstring);
XmlNodeList nodeList = doc.SelectNodes("blah/secondblah");

где X определено в библиотеке, которую мне предоставляют ИТ-специалисты, а ID - это int (примерно на котором я зацикливаюсь).

Это было тщательно протестировано в непараллельном контексте, string, созданные GetXML, действительно верны, соответствующие XmlDocument также, и "разбор" их с помощью XmlNodeList дает ожидаемые результаты.

Теперь, в этом параллельном контексте и при условии, что X и GetXML действительно потокобезопасны, обеспечивает ли тот факт, что я new и XmlDocument в каждом цикле, потокобезопасность или нет? Я имею в виду, как я могу узнать, что член string (во-первых, есть ли такая строка? поскольку я не вижу никакого свойства string в документе) XmlDocument, получающий LoadXml, является static или нет?

Я полагаю, что не совсем понимаю часть документации MSDN, которую я цитирую выше...


person Olorin    schedule 05.06.2017    source источник


Ответы (2)


Документация означает, что любые статические методы (которые выглядят как XmlDocument.MethodCall) являются потокобезопасными. Это не относится к вам — вы не вызываете ни один из них. Другие методы (например, для doc) не являются статическими. - поэтому их потокобезопасность не гарантируется.

Ваш код будет на 100% в порядке, если docnodeList, и другие «не потокобезопасные» переменные) используются исключительно в контексте одного потока.

Поэтому, если вы заполнили doc перед Parallel.ForEach, а затем использовали doc внутри Parallel.ForEach, это не сработает.

Но если вы заполняете и используете doc внутри Parallel.ForEach, все будет в порядке (поскольку каждый поток получит свой «собственный документ», поэтому безопасность потоков не будет проблемой).

Чтобы быть на 100% уверенным, вам нужно опубликовать весь метод (включая вызов Parallel.ForEach), чтобы мы могли его посмотреть.

person mjwills    schedule 05.06.2017
comment
Я подтверждаю, что doc (а также nodeList и другие «не потокобезопасные» переменные) используются исключительно в контексте одного потока. О документе: я вижу только упомянутые члены, а не методы. Я новичок в C#, поэтому пропустил какой-то словарный запас или ? - person Olorin; 05.06.2017
comment
Члены включают методы (код) и свойства (данные). - person Polyfun; 05.06.2017
comment
В контексте этого вопроса члены и методы эквивалентны. Извиняюсь за изменение терминологии на вас. - person mjwills; 05.06.2017

Да, это потокобезопасно. Вы ничего не делите между темами. Я без проблем использовал аналогичный код XmlDocument в больших многопоточных приложениях. Теоретически в XmlDocument могут быть частные статические данные, о которых мы не знаем, которые не являются потокобезопасными, но мой опыт показывает, что это не так. Я думаю, что документация MSDN подразумевает, что Microsoft позаботилась о том, чтобы любой статический материал, который может использоваться совместно между потоками, на самом деле был потокобезопасным.

person Polyfun    schedule 05.06.2017
comment
Да, в XmlDocument могут быть частные статические данные, о которых мы не знаем, которые не являются потокобезопасными, как раз моя точка зрения. - person Olorin; 05.06.2017
comment
Как ответил @mjwills перед вами, я приму его ответ, но ваш меня успокаивает! Большое спасибо. - person Olorin; 05.06.2017